Bug 1277214 - Move SafeIntent to its own class. r=grisha
This gets used often enough that it's annoying to do full class name imports.
MozReview-Commit-ID: 7Yhp1NCgwQw
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -49,17 +49,17 @@ import org.mozilla.gecko.home.HomePager.
import org.mozilla.gecko.home.HomePager.OnUrlOpenListener;
import org.mozilla.gecko.home.HomePanelsManager;
import org.mozilla.gecko.home.SearchEngine;
import org.mozilla.gecko.javaaddons.JavaAddonManager;
import org.mozilla.gecko.media.AudioFocusAgent;
import org.mozilla.gecko.menu.GeckoMenu;
import org.mozilla.gecko.menu.GeckoMenuItem;
import org.mozilla.gecko.mozglue.SafeIntentUtils;
-import org.mozilla.gecko.mozglue.SafeIntentUtils.SafeIntent;
+import org.mozilla.gecko.util.SafeIntent;
import org.mozilla.gecko.overlays.ui.ShareDialog;
import org.mozilla.gecko.permissions.Permissions;
import org.mozilla.gecko.preferences.ClearOnShutdownPref;
import org.mozilla.gecko.preferences.GeckoPreferences;
import org.mozilla.gecko.promotion.AddToHomeScreenPromotion;
import org.mozilla.gecko.delegates.BookmarkStateChangeDelegate;
import org.mozilla.gecko.promotion.ReaderViewBookmarkPromotion;
import org.mozilla.gecko.prompts.Prompt;
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -20,17 +20,17 @@ import org.mozilla.gecko.gfx.PluginLayer
import org.mozilla.gecko.health.HealthRecorder;
import org.mozilla.gecko.health.SessionInformation;
import org.mozilla.gecko.health.StubbedHealthRecorder;
import org.mozilla.gecko.home.HomeConfig.PanelType;
import org.mozilla.gecko.menu.GeckoMenu;
import org.mozilla.gecko.menu.GeckoMenuInflater;
import org.mozilla.gecko.menu.MenuPanel;
import org.mozilla.gecko.mozglue.SafeIntentUtils;
-import org.mozilla.gecko.mozglue.SafeIntentUtils.SafeIntent;
+import org.mozilla.gecko.util.SafeIntent;
import org.mozilla.gecko.mozglue.GeckoLoader;
import org.mozilla.gecko.permissions.Permissions;
import org.mozilla.gecko.preferences.ClearOnShutdownPref;
import org.mozilla.gecko.preferences.GeckoPreferences;
import org.mozilla.gecko.prompts.PromptService;
import org.mozilla.gecko.restrictions.Restrictions;
import org.mozilla.gecko.tabqueue.TabQueueHelper;
import org.mozilla.gecko.text.FloatingToolbarTextSelection;
--- a/mobile/android/base/java/org/mozilla/gecko/NotificationHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/NotificationHelper.java
@@ -7,17 +7,17 @@ package org.mozilla.gecko;
import java.util.HashMap;
import java.util.Iterator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.gfx.BitmapUtils;
-import org.mozilla.gecko.mozglue.SafeIntentUtils.SafeIntent;
+import org.mozilla.gecko.util.SafeIntent;
import org.mozilla.gecko.util.GeckoEventListener;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
--- a/mobile/android/base/java/org/mozilla/gecko/Tabs.java
+++ b/mobile/android/base/java/org/mozilla/gecko/Tabs.java
@@ -15,17 +15,17 @@ import android.support.annotation.Nullab
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.annotation.JNITarget;
import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.favicons.Favicons;
-import org.mozilla.gecko.mozglue.SafeIntentUtils.SafeIntent;
+import org.mozilla.gecko.util.SafeIntent;
import org.mozilla.gecko.notifications.WhatsNewReceiver;
import org.mozilla.gecko.reader.ReaderModeUtils;
import org.mozilla.gecko.util.GeckoEventListener;
import org.mozilla.gecko.util.ThreadUtils;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.OnAccountsUpdateListener;
--- a/mobile/android/base/java/org/mozilla/gecko/mozglue/GeckoLoader.java
+++ b/mobile/android/base/java/org/mozilla/gecko/mozglue/GeckoLoader.java
@@ -19,17 +19,17 @@ import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import org.mozilla.gecko.annotation.JNITarget;
import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.AppConstants;
-import org.mozilla.gecko.mozglue.SafeIntentUtils.SafeIntent;
+import org.mozilla.gecko.util.SafeIntent;
public final class GeckoLoader {
private static final String LOGTAG = "GeckoLoader";
private static volatile SafeIntent sIntent;
private static File sCacheFile;
private static File sGREDir;
--- a/mobile/android/base/java/org/mozilla/gecko/mozglue/SafeIntentUtils.java
+++ b/mobile/android/base/java/org/mozilla/gecko/mozglue/SafeIntentUtils.java
@@ -1,107 +1,25 @@
/* 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.mozglue;
import android.content.Intent;
-import android.net.Uri;
import android.os.Bundle;
-import android.util.Log;
+import org.mozilla.gecko.util.SafeIntent;
public class SafeIntentUtils {
- private static final String LOGTAG = "GeckoContextUtils";
public static Bundle getBundleExtra(final Intent intent, final String name) {
return new SafeIntent(intent).getBundleExtra(name);
}
public static String getStringExtra(final Intent intent, final String name) {
return new SafeIntent(intent).getStringExtra(name);
}
public static boolean getBooleanExtra(Intent intent, String name, boolean defaultValue) {
return new SafeIntent(intent).getBooleanExtra(name, defaultValue);
}
- /**
- * External applications can pass values into Intents that can cause us to crash: in defense,
- * we wrap {@link Intent} and catch the exceptions they may force us to throw. See bug 1090385
- * for more.
- */
- public static class SafeIntent {
- private final Intent intent;
-
- public SafeIntent(final Intent intent) {
- this.intent = intent;
- }
-
- public boolean getBooleanExtra(final String name, final boolean defaultValue) {
- try {
- return intent.getBooleanExtra(name, defaultValue);
- } catch (OutOfMemoryError e) {
- Log.w(LOGTAG, "Couldn't get intent extras: OOM. Malformed?");
- return defaultValue;
- } catch (RuntimeException e) {
- Log.w(LOGTAG, "Couldn't get intent extras.", e);
- return defaultValue;
- }
- }
-
- public String getStringExtra(final String name) {
- try {
- return intent.getStringExtra(name);
- } catch (OutOfMemoryError e) {
- Log.w(LOGTAG, "Couldn't get intent extras: OOM. Malformed?");
- return null;
- } catch (RuntimeException e) {
- Log.w(LOGTAG, "Couldn't get intent extras.", e);
- return null;
- }
- }
-
- public Bundle getBundleExtra(final String name) {
- try {
- return intent.getBundleExtra(name);
- } catch (OutOfMemoryError e) {
- Log.w(LOGTAG, "Couldn't get intent extras: OOM. Malformed?");
- return null;
- } catch (RuntimeException e) {
- Log.w(LOGTAG, "Couldn't get intent extras.", e);
- return null;
- }
- }
-
- public String getAction() {
- return intent.getAction();
- }
-
- public String getDataString() {
- try {
- return intent.getDataString();
- } catch (OutOfMemoryError e) {
- Log.w(LOGTAG, "Couldn't get intent data string: OOM. Malformed?");
- return null;
- } catch (RuntimeException e) {
- Log.w(LOGTAG, "Couldn't get intent data string.", e);
- return null;
- }
- }
-
- public Uri getData() {
- try {
- return intent.getData();
- } catch (OutOfMemoryError e) {
- Log.w(LOGTAG, "Couldn't get intent data: OOM. Malformed?");
- return null;
- } catch (RuntimeException e) {
- Log.w(LOGTAG, "Couldn't get intent data.", e);
- return null;
- }
- }
-
- public Intent getUnsafe() {
- return intent;
- }
- }
}
--- a/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueDispatcher.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueDispatcher.java
@@ -6,22 +6,22 @@
package org.mozilla.gecko.tabqueue;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.Locales;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.db.BrowserContract;
-import org.mozilla.gecko.mozglue.SafeIntentUtils;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
+import org.mozilla.gecko.util.SafeIntent;
/**
* This class takes over external url loads (Intent.VIEW) from the BrowserApp class. It determines if
* the tab queue functionality is enabled and forwards the intent to the TabQueueService to process if it is.
*
* If the tab queue functionality is not enabled then it forwards the intent to BrowserApp to handle as normal.
*/
public class TabQueueDispatcher extends Locales.LocaleAwareActivity {
@@ -35,17 +35,17 @@ public class TabQueueDispatcher extends
// The EXCLUDE_FROM_RECENTS flag is sticky
// (see http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.0_r1/com/android/server/am/ActivityRecord.java/#468)
// So let's remove this whilst keeping all other flags the same, otherwise BrowserApp will vanish from Recents!
Intent intent = getIntent();
int flags = intent.getFlags() & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
intent.setFlags(flags);
- SafeIntentUtils.SafeIntent safeIntent = new SafeIntentUtils.SafeIntent(intent);
+ SafeIntent safeIntent = new SafeIntent(intent);
// For the moment lets exit early and start fennec as normal if we're not in nightly with
// the tab queue build flag.
if (!TabQueueHelper.TAB_QUEUE_ENABLED) {
loadNormally(safeIntent.getUnsafe());
return;
}
--- a/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueService.java
@@ -6,17 +6,16 @@
package org.mozilla.gecko.tabqueue;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.R;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
-import org.mozilla.gecko.mozglue.SafeIntentUtils;
import org.mozilla.gecko.preferences.GeckoPreferences;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
@@ -35,16 +34,17 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
+import org.mozilla.gecko.util.SafeIntent;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* On launch this Service displays a View over the currently running process with an action to open the url in Fennec
@@ -126,17 +126,17 @@ public class TabQueueService extends Ser
// If this is a redelivery then lets bypass the entire double tap to open now code as that's a big can of worms,
// we also don't expect redeliveries because of the short time window associated with this feature.
if (flags != START_FLAG_REDELIVERY) {
final Context applicationContext = getApplicationContext();
final SharedPreferences sharedPreferences = GeckoSharedPrefs.forApp(applicationContext);
final String lastUrl = sharedPreferences.getString(GeckoPreferences.PREFS_TAB_QUEUE_LAST_SITE, "");
- final SafeIntentUtils.SafeIntent safeIntent = new SafeIntentUtils.SafeIntent(intent);
+ final SafeIntent safeIntent = new SafeIntent(intent);
final String intentUrl = safeIntent.getDataString();
final long lastRunTime = sharedPreferences.getLong(GeckoPreferences.PREFS_TAB_QUEUE_LAST_TIME, 0);
final boolean isWithinDoubleTapTimeLimit = System.currentTimeMillis() - lastRunTime < TOAST_DOUBLE_TAP_TIMEOUT_MILLIS;
if (!TextUtils.isEmpty(lastUrl) && lastUrl.equals(intentUrl) && isWithinDoubleTapTimeLimit) {
// Background thread because we could do some file IO if we have to remove a url from the list.
tabQueueHandler.post(new Runnable() {
@@ -272,17 +272,17 @@ public class TabQueueService extends Ser
}
private void addURLToTabQueue(final Intent intent, final String filename) {
if (intent == null) {
// This should never happen, but let's return silently instead of crashing if it does.
Log.w(LOGTAG, "Error adding URL to tab queue - invalid intent passed in.");
return;
}
- final SafeIntentUtils.SafeIntent safeIntent = new SafeIntentUtils.SafeIntent(intent);
+ final SafeIntent safeIntent = new SafeIntent(intent);
final String intentData = safeIntent.getDataString();
// As we're doing disk IO, let's run this stuff in a separate thread.
executorService.submit(new Runnable() {
@Override
public void run() {
Context applicationContext = getApplicationContext();
final GeckoProfile profile = GeckoProfile.get(applicationContext);
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/util/SafeIntent.java
@@ -0,0 +1,95 @@
+/*
+ * 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.util;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * External applications can pass values into Intents that can cause us to crash: in defense,
+ * we wrap {@link Intent} and catch the exceptions they may force us to throw. See bug 1090385
+ * for more.
+ */
+public class SafeIntent {
+ private static final String LOGTAG = "Gecko" + SafeIntent.class.getSimpleName();
+
+ private final Intent intent;
+
+ public SafeIntent(final Intent intent) {
+ this.intent = intent;
+ }
+
+ public boolean getBooleanExtra(final String name, final boolean defaultValue) {
+ try {
+ return intent.getBooleanExtra(name, defaultValue);
+ } catch (OutOfMemoryError e) {
+ Log.w(LOGTAG, "Couldn't get intent extras: OOM. Malformed?");
+ return defaultValue;
+ } catch (RuntimeException e) {
+ Log.w(LOGTAG, "Couldn't get intent extras.", e);
+ return defaultValue;
+ }
+ }
+
+ public String getStringExtra(final String name) {
+ try {
+ return intent.getStringExtra(name);
+ } catch (OutOfMemoryError e) {
+ Log.w(LOGTAG, "Couldn't get intent extras: OOM. Malformed?");
+ return null;
+ } catch (RuntimeException e) {
+ Log.w(LOGTAG, "Couldn't get intent extras.", e);
+ return null;
+ }
+ }
+
+ public Bundle getBundleExtra(final String name) {
+ try {
+ return intent.getBundleExtra(name);
+ } catch (OutOfMemoryError e) {
+ Log.w(LOGTAG, "Couldn't get intent extras: OOM. Malformed?");
+ return null;
+ } catch (RuntimeException e) {
+ Log.w(LOGTAG, "Couldn't get intent extras.", e);
+ return null;
+ }
+ }
+
+ public String getAction() {
+ return intent.getAction();
+ }
+
+ public String getDataString() {
+ try {
+ return intent.getDataString();
+ } catch (OutOfMemoryError e) {
+ Log.w(LOGTAG, "Couldn't get intent data string: OOM. Malformed?");
+ return null;
+ } catch (RuntimeException e) {
+ Log.w(LOGTAG, "Couldn't get intent data string.", e);
+ return null;
+ }
+ }
+
+ public Uri getData() {
+ try {
+ return intent.getData();
+ } catch (OutOfMemoryError e) {
+ Log.w(LOGTAG, "Couldn't get intent data: OOM. Malformed?");
+ return null;
+ } catch (RuntimeException e) {
+ Log.w(LOGTAG, "Couldn't get intent data.", e);
+ return null;
+ }
+ }
+
+ public Intent getUnsafe() {
+ return intent;
+ }
+}
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -123,16 +123,17 @@ gujar.sources += ['java/org/mozilla/geck
'util/NativeEventListener.java',
'util/NativeJSContainer.java',
'util/NativeJSObject.java',
'util/NetworkUtils.java',
'util/NonEvictingLruCache.java',
'util/PrefUtils.java',
'util/ProxySelector.java',
'util/RawResource.java',
+ 'util/SafeIntent.java',
'util/StringUtils.java',
'util/ThreadUtils.java',
'util/UIAsyncTask.java',
'util/UUIDUtil.java',
'util/WeakReferenceHandler.java',
'util/WebActivityMapper.java',
'util/WindowUtils.java',
]]