Bug 1359531 - Part 3 - Creating new intents is a job for IntentHelper. r=sebastian,walkingice
authorJan Henning <jh+bugzilla@buttercookie.de>
Fri, 28 Apr 2017 22:35:29 +0200
changeset 360093 8dbc1f7ec748b4f6c735cd05bd539ea96ded65f7
parent 360092 df8187a1ecc166d78120bdf1c201aa174437d32e
child 360094 46b245b80245182a89b51b4ec05a080e224080a6
push id31868
push userryanvm@gmail.com
push dateTue, 23 May 2017 14:32:52 +0000
treeherdermozilla-central@3a82a745123f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssebastian, walkingice
bugs1359531
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1359531 - Part 3 - Creating new intents is a job for IntentHelper. r=sebastian,walkingice MozReview-Commit-ID: 9s7aP35Q0AJ
mobile/android/base/java/org/mozilla/gecko/IntentHelper.java
mobile/android/base/java/org/mozilla/gecko/Tabs.java
mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java
--- a/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java
@@ -1,43 +1,53 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
  * 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;
 
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.mozilla.gecko.db.BrowserContract;
 import org.mozilla.gecko.overlays.ui.ShareDialog;
 import org.mozilla.gecko.util.ActivityResultHandler;
 import org.mozilla.gecko.util.BundleEventListener;
 import org.mozilla.gecko.util.EventCallback;
+import org.mozilla.gecko.util.FileUtils;
 import org.mozilla.gecko.util.GeckoBundle;
+import org.mozilla.gecko.webapps.WebAppActivity;
 import org.mozilla.gecko.widget.ExternalIntentDuringPrivateBrowsingPromptFragment;
 
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.provider.Browser;
 import android.support.annotation.Nullable;
 import android.support.v4.app.FragmentActivity;
 import android.text.TextUtils;
 import android.util.Log;
 import android.webkit.MimeTypeMap;
 
+import java.io.File;
+import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URLEncoder;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
 
+import static org.mozilla.gecko.Tabs.INTENT_EXTRA_SESSION_UUID;
+import static org.mozilla.gecko.Tabs.INTENT_EXTRA_TAB_ID;
+
 public final class IntentHelper implements BundleEventListener {
 
     private static final String LOGTAG = "GeckoIntentHelper";
     private static final String[] GECKO_EVENTS = {
         // Need to be on Gecko thread for synchronous callback.
         "Intent:GetHandlers",
     };
     private static final String[] UI_EVENTS = {
@@ -212,16 +222,61 @@ public final class IntentHelper implemen
 
         if (mimeType != null && mimeType.length() > 0) {
             shareIntent.setType(mimeType);
         }
 
         return shareIntent;
     }
 
+    public static Intent getTabSwitchIntent(final Tab tab) {
+        final Intent intent;
+        switch (tab.getType()) {
+            case CUSTOMTAB:
+                if (tab.getCustomTabIntent() != null) {
+                    intent = tab.getCustomTabIntent().getUnsafe();
+                } else {
+                    intent = new Intent(Intent.ACTION_VIEW);
+                    intent.setData(Uri.parse(tab.getURL()));
+                }
+                break;
+            case WEBAPP:
+                intent = new Intent(GeckoApp.ACTION_WEBAPP);
+                final String manifestPath = tab.getManifestPath();
+                try {
+                    intent.setData(getStartUriFromManifest(manifestPath));
+                } catch (IOException | JSONException e) {
+                    Log.e(LOGTAG, "Failed to get start URI from manifest", e);
+                    intent.setData(Uri.parse(tab.getURL()));
+                }
+                intent.putExtra(WebAppActivity.MANIFEST_PATH, manifestPath);
+                break;
+            default:
+                intent = new Intent(GeckoApp.ACTION_SWITCH_TAB);
+                break;
+        }
+
+        intent.setClassName(AppConstants.ANDROID_PACKAGE_NAME, tab.getTargetClassNameForTab());
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.putExtra(BrowserContract.SKIP_TAB_QUEUE_FLAG, true);
+        intent.putExtra(INTENT_EXTRA_TAB_ID, tab.getId());
+        intent.putExtra(INTENT_EXTRA_SESSION_UUID, GeckoApplication.getSessionUUID());
+        return intent;
+    }
+
+    // TODO: When things have settled down a bit, we should split this and everything similar
+    // TODO: in the WebAppActivity into a dedicated WebAppManifest class (bug 1353868).
+    private static Uri getStartUriFromManifest(String manifestPath) throws IOException, JSONException {
+        File manifestFile = new File(manifestPath);
+        final JSONObject manifest = FileUtils.readJSONObjectFromFile(manifestFile);
+        final JSONObject manifestField = manifest.getJSONObject("manifest");
+
+        return Uri.parse(manifestField.getString("start_url"));
+    }
+
     /**
      * Given a URI, a MIME type, an Android intent "action", and a title,
      * produce an intent which can be used to start an activity to open
      * the specified URI.
      *
      * @param context a <code>Context</code> instance.
      * @param targetURI the string spec of the URI to open.
      * @param mimeType an optional MIME type string.
--- a/mobile/android/base/java/org/mozilla/gecko/Tabs.java
+++ b/mobile/android/base/java/org/mozilla/gecko/Tabs.java
@@ -1,45 +1,39 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * 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;
 
-import java.io.File;
-import java.io.IOException;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import android.app.Activity;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 
-import org.json.JSONException;
-import org.json.JSONObject;
 import org.mozilla.gecko.annotation.JNITarget;
 import org.mozilla.gecko.annotation.RobocopTarget;
-import org.mozilla.gecko.db.BrowserContract;
 import org.mozilla.gecko.db.BrowserDB;
 import org.mozilla.gecko.distribution.PartnerBrowserCustomizationsClient;
 import org.mozilla.gecko.gfx.LayerView;
 import org.mozilla.gecko.mozglue.SafeIntent;
 import org.mozilla.gecko.notifications.WhatsNewReceiver;
 import org.mozilla.gecko.preferences.GeckoPreferences;
 import org.mozilla.gecko.reader.ReaderModeUtils;
 import org.mozilla.gecko.util.BundleEventListener;
 import org.mozilla.gecko.util.EventCallback;
-import org.mozilla.gecko.util.FileUtils;
 import org.mozilla.gecko.util.GeckoBundle;
 import org.mozilla.gecko.util.JavaUtil;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.webapps.WebAppActivity;
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.OnAccountsUpdateListener;
@@ -357,60 +351,20 @@ public class Tabs implements BundleEvent
      * Check whether the currently active activity matches the tab type of the passed tab.
      */
     public boolean currentActivityMatchesTab(Tab tab) {
         final Activity currentActivity = GeckoActivityMonitor.getInstance().getCurrentActivity();
         return currentActivity != null && tab.matchesActivity(currentActivity);
     }
 
     private void launchActivityForTab(Tab tab) {
-        final Intent intent;
-        switch (tab.getType()) {
-            case CUSTOMTAB:
-                if (tab.getCustomTabIntent() != null) {
-                    intent = tab.getCustomTabIntent().getUnsafe();
-                } else {
-                    intent = new Intent(Intent.ACTION_VIEW);
-                    intent.setData(Uri.parse(tab.getURL()));
-                }
-                break;
-            case WEBAPP:
-                intent = new Intent(GeckoApp.ACTION_WEBAPP);
-                final String manifestPath = tab.getManifestPath();
-                try {
-                    intent.setData(getStartUriFromManifest(manifestPath));
-                } catch (IOException | JSONException e) {
-                    Log.e(LOGTAG, "Failed to get start URI from manifest", e);
-                    intent.setData(Uri.parse(tab.getURL()));
-                }
-                intent.putExtra(WebAppActivity.MANIFEST_PATH, manifestPath);
-                break;
-            default:
-                intent = new Intent(GeckoApp.ACTION_SWITCH_TAB);
-                break;
-        }
-
-        intent.setClassName(AppConstants.ANDROID_PACKAGE_NAME, tab.getTargetClassNameForTab());
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.putExtra(BrowserContract.SKIP_TAB_QUEUE_FLAG, true);
-        intent.putExtra(INTENT_EXTRA_TAB_ID, tab.getId());
-        intent.putExtra(INTENT_EXTRA_SESSION_UUID, GeckoApplication.getSessionUUID());
+        final Intent intent = IntentHelper.getTabSwitchIntent(tab);
         mAppContext.startActivity(intent);
     }
 
-    // TODO: When things have settled down a bit, we should split this and everything similar
-    // TODO: in the WebAppActivity into a dedicated WebAppManifest class (bug 1353868).
-    private Uri getStartUriFromManifest(String manifestPath) throws IOException, JSONException {
-        File manifestFile = new File(manifestPath);
-        final JSONObject manifest = FileUtils.readJSONObjectFromFile(manifestFile);
-        final JSONObject manifestField = manifest.getJSONObject("manifest");
-
-        return Uri.parse(manifestField.getString("start_url"));
-    }
-
     public synchronized boolean selectLastTab() {
         if (mOrder.isEmpty()) {
             return false;
         }
 
         selectTab(mOrder.get(mOrder.size() - 1).getId());
         return true;
     }
--- a/mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java
@@ -22,16 +22,17 @@ import android.os.IBinder;
 import android.support.annotation.CheckResult;
 import android.support.annotation.VisibleForTesting;
 import android.support.v4.app.NotificationManagerCompat;
 import android.util.Log;
 
 import org.mozilla.gecko.BrowserApp;
 import org.mozilla.gecko.GeckoApp;
 import org.mozilla.gecko.GeckoAppShell;
+import org.mozilla.gecko.IntentHelper;
 import org.mozilla.gecko.PrefsHelper;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.Tab;
 import org.mozilla.gecko.Tabs;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import java.lang.ref.WeakReference;
 
@@ -397,17 +398,17 @@ public class MediaControlService extends
         final int visibility = tab.isPrivate() ?
             Notification.VISIBILITY_PRIVATE : Notification.VISIBILITY_PUBLIC;
 
         final Notification notification = new Notification.Builder(this)
             .setSmallIcon(R.drawable.flat_icon)
             .setLargeIcon(generateCoverArt(tab))
             .setContentTitle(tab.getTitle())
             .setContentText(tab.getURL())
-            .setContentIntent(createContentIntent(tab.getId()))
+            .setContentIntent(createContentIntent(tab))
             .setDeleteIntent(createDeleteIntent())
             .setStyle(style)
             .addAction(createNotificationAction())
             .setOngoing(isPlaying)
             .setShowWhen(false)
             .setWhen(0)
             .setVisibility(visibility)
             .build();
@@ -442,20 +443,18 @@ public class MediaControlService extends
     @VisibleForTesting
     protected Intent createIntentUponState(State state) {
         String action = state.equals(State.PLAYING) ? ACTION_PAUSE : ACTION_RESUME;
         final Intent intent = new Intent(getApplicationContext(), MediaControlService.class);
         intent.setAction(action);
         return intent;
     }
 
-    private PendingIntent createContentIntent(int tabId) {
-        Intent intent = new Intent(getApplicationContext(), BrowserApp.class);
-        intent.setAction(GeckoApp.ACTION_SWITCH_TAB);
-        intent.putExtra(Tabs.INTENT_EXTRA_TAB_ID, tabId);
+    private PendingIntent createContentIntent(Tab tab) {
+        Intent intent = IntentHelper.getTabSwitchIntent(tab);
         return PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
     private PendingIntent createDeleteIntent() {
         Intent intent = new Intent(getApplicationContext(), MediaControlService.class);
         intent.setAction(ACTION_STOP);
         return  PendingIntent.getService(getApplicationContext(), 1, intent, 0);
     }