Bug 1299939 - Use SafeIntent to handle incoming intents in the LauncherActivity r=sebastian draft
authorGrigory Kruglov <gkruglov@mozilla.com>
Thu, 01 Sep 2016 16:35:59 -0700
changeset 408998 4ab2533c08484f4dadb19d0a29ea4635803f4991
parent 408867 3ba5426a03b495b6417fffb872d42874edb80855
child 408999 2a33364e68935be46a9c8991bbad25cdeab06cc0
child 409014 9b11043d6607c15674e063ada5546a9dd00cbc23
push id28351
push usergkruglov@mozilla.com
push dateThu, 01 Sep 2016 23:58:13 +0000
reviewerssebastian
bugs1299939
milestone51.0a1
Bug 1299939 - Use SafeIntent to handle incoming intents in the LauncherActivity r=sebastian MozReview-Commit-ID: 49zDp3A4dnG
mobile/android/base/java/org/mozilla/gecko/LauncherActivity.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/SafeIntent.java
--- a/mobile/android/base/java/org/mozilla/gecko/LauncherActivity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/LauncherActivity.java
@@ -3,59 +3,62 @@
  * 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;
 
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
+import android.support.annotation.NonNull;
 import android.support.customtabs.CustomTabsIntent;
 
 import org.mozilla.gecko.customtabs.CustomTabsActivity;
 import org.mozilla.gecko.db.BrowserContract;
+import org.mozilla.gecko.mozglue.SafeIntent;
 import org.mozilla.gecko.preferences.GeckoPreferences;
 import org.mozilla.gecko.tabqueue.TabQueueHelper;
 import org.mozilla.gecko.tabqueue.TabQueueService;
 
 /**
  * Activity that receives incoming Intents and dispatches them to the appropriate activities (e.g. browser, custom tabs, web app).
  */
 public class LauncherActivity extends Activity {
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
         GeckoAppShell.ensureCrashHandling();
 
-        if (AppConstants.MOZ_ANDROID_CUSTOM_TABS && isCustomTabsIntent() && isCustomTabsEnabled()) {
+        final SafeIntent safeIntent = new SafeIntent(getIntent());
+
+        // If it's not a view intent, it won't be a custom tabs intent either. Just launch!
+        if (!isViewIntentWithURL(safeIntent)) {
+            dispatchNormalIntent();
+
+        // Is this a custom tabs intent, and are custom tabs enabled?
+        } else if (AppConstants.MOZ_ANDROID_CUSTOM_TABS && isCustomTabsIntent(safeIntent)
+                && isCustomTabsEnabled()) {
             dispatchCustomTabsIntent();
-        } else if (isViewIntentWithURL()) {
-            dispatchViewIntent();
+
+        // Can we dispatch this VIEW action intent to the tab queue service?
+        } else if (!safeIntent.getBooleanExtra(BrowserContract.SKIP_TAB_QUEUE_FLAG, false)
+                && TabQueueHelper.TAB_QUEUE_ENABLED
+                && TabQueueHelper.isTabQueueEnabled(this)) {
+            dispatchTabQueueIntent();
+
+        // Dispatch this VIEW action intent to the browser.
         } else {
             dispatchNormalIntent();
         }
 
         finish();
     }
 
     /**
-     * Dispatch a VIEW action intent; either to the browser or to the tab queue service.
-     */
-    private void dispatchViewIntent() {
-        if (TabQueueHelper.TAB_QUEUE_ENABLED
-                && TabQueueHelper.isTabQueueEnabled(this)
-                && !getIntent().getBooleanExtra(BrowserContract.SKIP_TAB_QUEUE_FLAG, false)) {
-            dispatchTabQueueIntent();
-        } else {
-            dispatchNormalIntent();
-        }
-    }
-
-    /**
      * Launch tab queue service to display overlay.
      */
     private void dispatchTabQueueIntent() {
         Intent intent = new Intent(getIntent());
         intent.setClass(getApplicationContext(), TabQueueService.class);
         startService(intent);
     }
 
@@ -69,24 +72,22 @@ public class LauncherActivity extends Ac
     }
 
     private void dispatchCustomTabsIntent() {
         Intent intent = new Intent(getIntent());
         intent.setClassName(getApplicationContext(), CustomTabsActivity.class.getName());
         startActivity(intent);
     }
 
-    private boolean isViewIntentWithURL() {
-        final Intent intent = getIntent();
-
-        return Intent.ACTION_VIEW.equals(intent.getAction())
-                && intent.getDataString() != null;
+    private static boolean isViewIntentWithURL(@NonNull final SafeIntent safeIntent) {
+        return Intent.ACTION_VIEW.equals(safeIntent.getAction())
+                && safeIntent.getDataString() != null;
     }
 
-    private boolean isCustomTabsIntent() {
-        return isViewIntentWithURL()
-                && getIntent().hasExtra(CustomTabsIntent.EXTRA_SESSION);
+    private static boolean isCustomTabsIntent(@NonNull final SafeIntent safeIntent) {
+        return isViewIntentWithURL(safeIntent)
+                && safeIntent.hasExtra(CustomTabsIntent.EXTRA_SESSION);
     }
 
     private boolean isCustomTabsEnabled() {
         return GeckoSharedPrefs.forApp(this).getBoolean(GeckoPreferences.PREFS_CUSTOM_TABS, false);
     }
 }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/SafeIntent.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/SafeIntent.java
@@ -21,16 +21,28 @@ 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 hasExtra(String name) {
+        try {
+            return intent.hasExtra(name);
+        } catch (OutOfMemoryError e) {
+            Log.w(LOGTAG, "Couldn't determine if intent had an extra: OOM. Malformed?");
+            return false;
+        } catch (RuntimeException e) {
+            Log.w(LOGTAG, "Couldn't determine if intent had an extra.", e);
+            return false;
+        }
+    }
+
     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);