Bug 1277214 - Move SafeIntent to its own class. r=grisha draft
authorMichael Comella <michael.l.comella@gmail.com>
Wed, 01 Jun 2016 15:27:41 -0700
changeset 374142 c6ab0adc687381281fb819c836c74897252b3daf
parent 374141 ff54f55a0eafd51ee91e07aa1b5bc6200af2adb7
child 374143 c03e0c52b9b5a16d651547fb7176dd79c0ed0ecf
push id19946
push usermichael.l.comella@gmail.com
push dateWed, 01 Jun 2016 23:55:51 +0000
reviewersgrisha
bugs1277214
milestone49.0a1
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
mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
mobile/android/base/java/org/mozilla/gecko/NotificationHelper.java
mobile/android/base/java/org/mozilla/gecko/Tabs.java
mobile/android/base/java/org/mozilla/gecko/mozglue/GeckoLoader.java
mobile/android/base/java/org/mozilla/gecko/mozglue/SafeIntentUtils.java
mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueDispatcher.java
mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueService.java
mobile/android/base/java/org/mozilla/gecko/util/SafeIntent.java
mobile/android/base/moz.build
--- 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',
 ]]