Bug 1442255 - 4. Use extras bundle to initialize Gecko in Fennec; r=esawin draft
authorJim Chen <nchen@mozilla.com>
Tue, 06 Mar 2018 13:52:50 -0500
changeset 763802 89b93e482eb4cd90760fd22f7702b6c1fa71ec10
parent 763801 aff22f8bf60ffea43a615b9ea7f7ffa2b32291fb
child 763803 48df1d42d75db9cf5e562d7ee294c938ea765699
push id101565
push userbmo:nchen@mozilla.com
push dateTue, 06 Mar 2018 18:53:11 +0000
reviewersesawin
bugs1442255
milestone60.0a1
Bug 1442255 - 4. Use extras bundle to initialize Gecko in Fennec; r=esawin Use extras bundle (e.g. from an Intent) to initialize Gecko in GeckoApp and GeckoService. MozReview-Commit-ID: AmLZ8Uir8f4
mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
mobile/android/base/java/org/mozilla/gecko/GeckoService.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/SafeIntent.java
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -964,21 +964,16 @@ public abstract class GeckoApp extends G
         // The clock starts...now. Better hurry!
         mJavaUiStartupTimer = new Telemetry.UptimeTimer("FENNEC_STARTUP_TIME_JAVAUI");
         mGeckoReadyStartupTimer = new Telemetry.UptimeTimer("FENNEC_STARTUP_TIME_GECKOREADY");
 
         final SafeIntent intent = new SafeIntent(getIntent());
 
         earlyStartJavaSampler(intent);
 
-        // GeckoLoader wants to dig some environment variables out of the
-        // incoming intent, so pass it in here. GeckoLoader will do its
-        // business later and dispose of the reference.
-        GeckoLoader.setLastIntent(intent);
-
         // Workaround for <http://code.google.com/p/android/issues/detail?id=20915>.
         try {
             Class.forName("android.os.AsyncTask");
         } catch (ClassNotFoundException e) { }
 
         GeckoAppShell.setScreenOrientationDelegate(this);
 
         // Tell Stumbler to register a local broadcast listener to listen for preference intents.
@@ -1007,22 +1002,22 @@ public abstract class GeckoApp extends G
             // without killing the entire application (see Bug 769269).
             // In case we have multiple GeckoApp-based activities, this can
             // also happen if we're not the first activity to run within a session.
             mIsRestoringActivity = true;
             Telemetry.addToHistogram("FENNEC_RESTORING_ACTIVITY", 1);
 
         } else {
             final String action = intent.getAction();
-            final String args = GeckoApplication.addDefaultGeckoArgs(
-                    intent.getStringExtra("args"));
+            final String[] args = GeckoApplication.getDefaultGeckoArgs();
             final int flags = ACTION_DEBUG.equals(action) ? GeckoThread.FLAG_DEBUGGING : 0;
 
             sAlreadyLoaded = true;
-            GeckoThread.initMainProcess(/* profile */ null, args, flags);
+            GeckoThread.initMainProcess(/* profile */ null, args,
+                                        intent.getExtras(), flags);
 
             // Speculatively pre-fetch the profile in the background.
             ThreadUtils.postToBackgroundThread(new Runnable() {
                 @Override
                 public void run() {
                     getProfile();
                 }
             });
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
@@ -12,16 +12,17 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Environment;
 import android.os.Process;
 import android.os.SystemClock;
 import android.provider.MediaStore;
+import android.support.annotation.Nullable;
 import android.support.design.widget.Snackbar;
 import android.text.TextUtils;
 import android.util.Base64;
 import android.util.Log;
 
 import com.squareup.leakcanary.LeakCanary;
 import com.squareup.leakcanary.RefWatcher;
 
@@ -97,27 +98,27 @@ public class GeckoApplication extends Ap
 
     /**
      * @return The string representation of an UUID that changes on each application startup.
      */
     public static String getSessionUUID() {
         return sSessionUUID;
     }
 
-    public static String addDefaultGeckoArgs(String args) {
+    public static @Nullable String[] getDefaultGeckoArgs() {
         if (!AppConstants.MOZILLA_OFFICIAL) {
             // In un-official builds, we want to load Javascript resources fresh
             // with each build.  In official builds, the startup cache is purged by
             // the buildid mechanism, but most un-official builds don't bump the
             // buildid, so we purge here instead.
             Log.w(LOG_TAG, "STARTUP PERFORMANCE WARNING: un-official build: purging the " +
                            "startup (JavaScript) caches.");
-            args = (args != null) ? (args + " -purgecaches") : "-purgecaches";
+            return new String[] { "-purgecaches" };
         }
-        return args;
+        return null;
     }
 
     public static String getDefaultUAString() {
         return HardwareUtils.isTablet() ? AppConstants.USER_AGENT_FENNEC_TABLET :
                                           AppConstants.USER_AGENT_FENNEC_MOBILE;
     }
 
     public static void shutdown(final Intent restartIntent) {
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoService.java
@@ -5,16 +5,17 @@
 
 package org.mozilla.gecko;
 
 import android.app.AlarmManager;
 import android.app.Service;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Handler;
 import android.os.Looper;
 import android.util.Log;
 
 import java.io.File;
 
 import org.mozilla.gecko.util.BundleEventListener;
@@ -110,16 +111,21 @@ public class GeckoService extends Servic
         if (DEBUG) {
             Log.d(LOGTAG, "Destroyed");
         }
         super.onDestroy();
     }
 
     private static Intent getIntentForAction(final Context context, final String action) {
         final Intent intent = new Intent(action, /* uri */ null, context, GeckoService.class);
+        final Bundle extras = GeckoThread.getActiveExtras();
+        if (extras != null && extras.size() > 0) {
+            intent.replaceExtras(extras);
+        }
+
         final GeckoProfile profile = GeckoThread.getActiveProfile();
         if (profile != null) {
             setIntentProfile(intent, profile.getName(), profile.getDir().getAbsolutePath());
         }
         return intent;
     }
 
     public static Intent getIntentToCreateServices(final Context context, final String category, final String data) {
@@ -157,17 +163,17 @@ public class GeckoService extends Servic
         final String profileDir = intent.getStringExtra(INTENT_PROFILE_DIR);
 
         if (profileName == null) {
             throw new IllegalArgumentException("Intent must specify profile.");
         }
 
         if (!GeckoThread.initMainProcessWithProfile(
                 profileName, profileDir != null ? new File(profileDir) : null,
-                GeckoApplication.addDefaultGeckoArgs(null))) {
+                GeckoApplication.getDefaultGeckoArgs(), intent.getExtras())) {
             Log.w(LOGTAG, "Ignoring due to profile mismatch: " +
                           profileName + " [" + profileDir + ']');
 
             final GeckoProfile profile = GeckoThread.getActiveProfile();
             if (profile != null) {
                 Log.w(LOGTAG, "Current profile is " + profile.getName() +
                               " [" + profile.getDir().getAbsolutePath() + ']');
             }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java
@@ -25,16 +25,17 @@ import android.os.SystemClock;
 import android.support.annotation.Nullable;
 import android.text.TextUtils;
 import android.util.Log;
 
 import java.io.File;
 import java.io.FilenameFilter;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Locale;
 import java.util.StringTokenizer;
 
 public class GeckoThread extends Thread {
     private static final String LOGTAG = "GeckoThread";
 
     public enum State implements NativeQueue.State {
         // After being loaded by class loader.
@@ -319,16 +320,20 @@ public class GeckoThread extends Thread 
             args.add("-profile");
             args.add(profile.getDir().getAbsolutePath());
         } else {
             profile.getDir(); // Make sure the profile dir exists.
             args.add("-P");
             args.add(profile.getName());
         }
 
+        if (mArgs != null) {
+            args.addAll(Arrays.asList(mArgs));
+        }
+
         final String extraArgs = mExtras.getString(EXTRA_ARGS, null);
         if (extraArgs != null) {
             final StringTokenizer st = new StringTokenizer(extraArgs);
             while (st.hasMoreTokens()) {
                 final String token = st.nextToken();
                 if ("-P".equals(token) || "-profile".equals(token)) {
                     // Skip -P and -profile arguments because we added them above.
                     if (st.hasMoreTokens()) {
--- 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
@@ -5,16 +5,17 @@
  */
 
 // This should be in util/, but is here because of build dependency issues.
 package org.mozilla.gecko.mozglue;
 
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
+import android.support.annotation.Nullable;
 import android.util.Log;
 
 import java.util.ArrayList;
 
 /**
  * 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.
@@ -36,16 +37,28 @@ public class SafeIntent {
             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 @Nullable Bundle getExtras() {
+        try {
+            return intent.getExtras();
+        } 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 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);