Backed out 7 changesets (bug 1442255) for failing c1 tests on mochitest/test_browserElement_inproc_PurgeHistory.html
authorGurzau Raul <rgurzau@mozilla.com>
Tue, 06 Mar 2018 17:08:57 +0200
changeset 406730 b1dc3a24a077e384e3c439453cd800636e2cf173
parent 406729 dc1a57e1430e18392d59e30c75d5cb5f69943e73
child 406731 4fa35b9daa651d33a7c6de3a430e9cb385c0922b
push id33576
push userdluca@mozilla.com
push dateTue, 06 Mar 2018 18:34:13 +0000
treeherdermozilla-central@b498494cfac5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1442255
milestone60.0a1
backs out208c4c42f641e189ac930ef0831b38d502c7374c
6a794e14fcebb137e82ca679fd647680fe31d3fe
62d1c57c37b46778999b628196decfa5c5fa7d27
5d0f72867f53c055f461321798a08ce09d6889c6
c3305648ad30458a5eb098c6f4fdea5358d339a0
08f906f3a0c836d333699f528f70a6b86a69f5eb
d7a43e59a1b4ea7c294e7645c4f77d798fe7be67
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
Backed out 7 changesets (bug 1442255) for failing c1 tests on mochitest/test_browserElement_inproc_PurgeHistory.html Backed out changeset 208c4c42f641 (bug 1442255) Backed out changeset 6a794e14fceb (bug 1442255) Backed out changeset 62d1c57c37b4 (bug 1442255) Backed out changeset 5d0f72867f53 (bug 1442255) Backed out changeset c3305648ad30 (bug 1442255) Backed out changeset 08f906f3a0c8 (bug 1442255) Backed out changeset d7a43e59a1b4 (bug 1442255)
ipc/glue/GeckoChildProcessHost.cpp
mobile/android/app/geckoview-prefs.js
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/androidTest/java/org/mozilla/geckoview/test/TestRunnerActivity.java
mobile/android/geckoview/src/main/aidl/org/mozilla/gecko/process/IChildProcess.aidl
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/SafeIntent.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/process/GeckoProcessManager.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/process/GeckoServiceChildProcess.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
mozglue/android/APKOpen.cpp
toolkit/xre/Bootstrap.cpp
toolkit/xre/Bootstrap.h
toolkit/xre/nsEmbedFunctions.cpp
xpcom/build/nsXULAppAPI.h
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -1198,15 +1198,15 @@ GeckoChildProcessHost::LaunchAndroidServ
   if (it != fds_to_remap.end() && !CrashReporter::IsDummy()) {
     crashFd = it->first;
     it++;
   }
   if (it != fds_to_remap.end()) {
     crashAnnotationFd = it->first;
     it++;
   }
-  int32_t handle = java::GeckoProcessManager::Start(type, jargs, ipcFd, crashFd, crashAnnotationFd);
+  int32_t handle = java::GeckoProcessManager::Start(type, jargs, crashFd, ipcFd, crashAnnotationFd);
 
   if (process_handle) {
     *process_handle = handle;
   }
 }
 #endif
--- a/mobile/android/app/geckoview-prefs.js
+++ b/mobile/android/app/geckoview-prefs.js
@@ -2,9 +2,8 @@
  * 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/. */
 
 #filter substitution
 
 #include mobile.js
 
 pref("privacy.trackingprotection.pbmode.enabled", false);
-pref("dom.ipc.processCount", 1);
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -964,16 +964,21 @@ 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.
@@ -1002,22 +1007,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.getDefaultGeckoArgs();
+            final String args = GeckoApplication.addDefaultGeckoArgs(
+                    intent.getStringExtra("args"));
             final int flags = ACTION_DEBUG.equals(action) ? GeckoThread.FLAG_DEBUGGING : 0;
 
             sAlreadyLoaded = true;
-            GeckoThread.initMainProcess(/* profile */ null, args,
-                                        intent.getExtras(), flags);
+            GeckoThread.initMainProcess(/* profile */ null, args, 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,17 +12,16 @@ 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;
 
@@ -98,27 +97,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 @Nullable String[] getDefaultGeckoArgs() {
+    public static String addDefaultGeckoArgs(String args) {
         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.");
-            return new String[] { "-purgecaches" };
+            args = (args != null) ? (args + " -purgecaches") : "-purgecaches";
         }
-        return null;
+        return args;
     }
 
     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,17 +5,16 @@
 
 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;
@@ -111,21 +110,16 @@ 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) {
@@ -163,17 +157,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.getDefaultGeckoArgs(), intent.getExtras())) {
+                GeckoApplication.addDefaultGeckoArgs(null))) {
             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/androidTest/java/org/mozilla/geckoview/test/TestRunnerActivity.java
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestRunnerActivity.java
@@ -96,19 +96,22 @@ public class TestRunnerActivity extends 
         session.openWindow(this);
         return session;
     }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        final Intent intent = getIntent();
-        GeckoSession.preload(this, new String[] { "-purgecaches" },
-                             intent.getExtras(), false /* no multiprocess, see below */);
+        Intent intent = getIntent();
+        GeckoLoader.setLastIntent(new SafeIntent(getIntent()));
+
+        final String intentArgs = intent.getStringExtra("args");
+        final String args = intentArgs != null ? "-purgecaches " + intentArgs : "-purgecaches";
+        GeckoSession.preload(this, args, false /* no multiprocess, see below */);
 
         // We can't use e10s because we get deadlocked when quickly creating and
         // destroying sessions. Bug 1348361.
         mSession = createSession();
 
         // If we were passed a URI in the Intent, open it
         final Uri uri = intent.getData();
         if (uri != null) {
--- a/mobile/android/geckoview/src/main/aidl/org/mozilla/gecko/process/IChildProcess.aidl
+++ b/mobile/android/geckoview/src/main/aidl/org/mozilla/gecko/process/IChildProcess.aidl
@@ -1,17 +1,14 @@
 /* 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.process;
 
 import org.mozilla.gecko.process.IProcessManager;
 
-import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 
 interface IChildProcess {
     int getPid();
-    boolean start(in IProcessManager procMan, in String[] args, in Bundle extras,
-                  in ParcelFileDescriptor ipcPfd, in ParcelFileDescriptor crashReporterPfd,
-                  in ParcelFileDescriptor crashAnnotationPfd);
+    boolean start(in IProcessManager procMan, in String[] args, in ParcelFileDescriptor crashReporterPfd, in ParcelFileDescriptor ipcPfd, in ParcelFileDescriptor crashAnnotationPfd);
 }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java
@@ -11,31 +11,28 @@ import org.mozilla.gecko.mozglue.GeckoLo
 import org.mozilla.gecko.process.GeckoProcessManager;
 import org.mozilla.gecko.util.GeckoBundle;
 import org.mozilla.gecko.util.FileUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.MessageQueue;
 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.
@@ -118,76 +115,77 @@ public class GeckoThread extends Thread 
 
     @WrapForJNI
     private static final ClassLoader clsLoader = GeckoThread.class.getClassLoader();
     @WrapForJNI
     private static MessageQueue msgQueue;
     @WrapForJNI
     private static int uiThreadId;
 
+    private boolean mInitialized;
+    private String[] mArgs;
+
     // Main process parameters
     public static final int FLAG_DEBUGGING = 1; // Debugging mode.
     public static final int FLAG_PRELOAD_CHILD = 2; // Preload child during main thread start.
 
-    private static final String EXTRA_ARGS = "args";
-    private static final String EXTRA_IPC_FD = "ipcFd";
-    private static final String EXTRA_CRASH_FD = "crashFd";
-    private static final String EXTRA_CRASH_ANNOTATION_FD = "crashAnnotationFd";
+    private GeckoProfile mProfile;
+    private String mExtraArgs;
+    private int mFlags;
 
-    private boolean mInitialized;
-    private GeckoProfile mProfile;
-    private String[] mArgs;
-    private Bundle mExtras;
-    private int mFlags;
+    // Child process parameters
+    private int mCrashFileDescriptor = -1;
+    private int mIPCFileDescriptor = -1;
+    private int mCrashAnnotationFileDescriptor = -1;
 
     GeckoThread() {
         setName("Gecko");
     }
 
     @WrapForJNI
     private static boolean isChildProcess() {
-        return INSTANCE.mExtras.getInt(EXTRA_IPC_FD, -1) != -1;
+        return INSTANCE.mIPCFileDescriptor != -1;
     }
 
     private synchronized boolean init(final GeckoProfile profile, final String[] args,
-                                      final Bundle extras, final int flags,
-                                      final int ipcFd, final int crashFd,
+                                      final String extraArgs, final int flags,
+                                      final int crashFd, final int ipcFd,
                                       final int crashAnnotationFd) {
         ThreadUtils.assertOnUiThread();
         uiThreadId = android.os.Process.myTid();
 
         if (mInitialized) {
             return false;
         }
 
         mProfile = profile;
         mArgs = args;
+        mExtraArgs = extraArgs;
         mFlags = flags;
-
-        mExtras = (extras != null) ? new Bundle(extras) : new Bundle(3);
-        mExtras.putInt(EXTRA_IPC_FD, ipcFd);
-        mExtras.putInt(EXTRA_CRASH_FD, crashFd);
-        mExtras.putInt(EXTRA_CRASH_ANNOTATION_FD, crashAnnotationFd);
+        mCrashFileDescriptor = crashFd;
+        mIPCFileDescriptor = ipcFd;
+        mCrashAnnotationFileDescriptor = crashAnnotationFd;
 
         mInitialized = true;
         notifyAll();
         return true;
     }
 
-    public static boolean initMainProcess(final GeckoProfile profile, final String[] args,
-                                          final Bundle extras, final int flags) {
-        return INSTANCE.init(profile, args, extras, flags,
-                             /* fd */ -1, /* fd */ -1, /* fd */ -1);
+    public static boolean initMainProcess(final GeckoProfile profile, final String extraArgs,
+                                          final int flags) {
+        return INSTANCE.init(profile, /* args */ null, extraArgs, flags,
+                                 /* crashFd */ -1, /* ipcFd */ -1,
+                                 /* crashAnnotationFd */ -1);
     }
 
-    public static boolean initChildProcess(final String[] args, final Bundle extras,
-                                           final int ipcFd, final int crashFd,
+    public static boolean initChildProcess(final String[] args, final int crashFd,
+                                           final int ipcFd,
                                            final int crashAnnotationFd) {
-        return INSTANCE.init(/* profile */ null, args, extras, /* flags */ 0,
-                             ipcFd, crashFd, crashAnnotationFd);
+        return INSTANCE.init(/* profile */ null, args, /* extraArgs */ null,
+                                 /* flags */ 0, crashFd, ipcFd, crashAnnotationFd);
     }
 
     private static boolean canUseProfile(final Context context, final GeckoProfile profile,
                                          final String profileName, final File profileDir) {
         if (profileDir != null && !profileDir.isDirectory()) {
             return false;
         }
 
@@ -212,18 +210,17 @@ public class GeckoThread extends Thread 
             throw new IllegalArgumentException("Null profile name");
         }
         return canUseProfile(GeckoAppShell.getApplicationContext(), getActiveProfile(),
                              profileName, profileDir);
     }
 
     public static boolean initMainProcessWithProfile(final String profileName,
                                                      final File profileDir,
-                                                     final String[] args,
-                                                     final Bundle extras) {
+                                                     final String args) {
         if (profileName == null) {
             throw new IllegalArgumentException("Null profile name");
         }
 
         final Context context = GeckoAppShell.getApplicationContext();
         final GeckoProfile profile = getActiveProfile();
 
         if (!canUseProfile(context, profile, profileName, profileDir)) {
@@ -232,18 +229,18 @@ public class GeckoThread extends Thread 
         }
 
         if (profile != null) {
             // We already have a compatible profile.
             return true;
         }
 
         // We haven't initialized yet; okay to initialize now.
-        return initMainProcess(GeckoProfile.get(context, profileName, profileDir), args,
-                               extras, /* flags */ 0);
+        return initMainProcess(GeckoProfile.get(context, profileName, profileDir),
+                               args, /* flags */ 0);
     }
 
     public static boolean launch() {
         ThreadUtils.assertOnUiThread();
 
         if (checkAndSetState(State.INITIAL, State.LAUNCHED)) {
             INSTANCE.start();
             return true;
@@ -262,33 +259,33 @@ public class GeckoThread extends Thread 
 
     private static void loadGeckoLibs(final Context context, final String resourcePath) {
         GeckoLoader.loadSQLiteLibs(context, resourcePath);
         GeckoLoader.loadNSSLibs(context, resourcePath);
         GeckoLoader.loadGeckoLibs(context, resourcePath);
         setState(State.LIBS_READY);
     }
 
-    private static void initGeckoEnvironment(final Bundle extras) {
+    private static void initGeckoEnvironment() {
         final Context context = GeckoAppShell.getApplicationContext();
         GeckoLoader.loadMozGlue(context);
         setState(State.MOZGLUE_READY);
 
         final Locale locale = Locale.getDefault();
         final Resources res = context.getResources();
         if (locale.toString().equalsIgnoreCase("zh_hk")) {
             final Locale mappedLocale = Locale.TRADITIONAL_CHINESE;
             Locale.setDefault(mappedLocale);
             Configuration config = res.getConfiguration();
             config.locale = mappedLocale;
             res.updateConfiguration(config, null);
         }
 
         final String resourcePath = context.getPackageResourcePath();
-        GeckoLoader.setupGeckoEnvironment(context, context.getFilesDir().getPath(), extras);
+        GeckoLoader.setupGeckoEnvironment(context, context.getFilesDir().getPath());
 
         try {
             loadGeckoLibs(context, resourcePath);
             return;
         } catch (final Exception e) {
             // Cannot load libs; try clearing the cached files.
             Log.w(LOGTAG, "Clearing cache after load libs exception", e);
         }
@@ -321,23 +318,18 @@ 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);
+        if (mExtraArgs != null) {
+            final StringTokenizer st = new StringTokenizer(mExtraArgs);
             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()) {
                         st.nextToken();
                     }
                     continue;
@@ -359,30 +351,21 @@ public class GeckoThread extends Thread 
             return null;
         }
         if (isChildProcess()) {
             throw new UnsupportedOperationException(
                     "Cannot access profile from child process");
         }
         if (mProfile == null) {
             final Context context = GeckoAppShell.getApplicationContext();
-            mProfile = GeckoProfile.initFromArgs(context, mExtras.getString(EXTRA_ARGS, null));
+            mProfile = GeckoProfile.initFromArgs(context, mExtraArgs);
         }
         return mProfile;
     }
 
-    public static @Nullable Bundle getActiveExtras() {
-        synchronized (INSTANCE) {
-            if (!INSTANCE.mInitialized) {
-                return null;
-            }
-            return INSTANCE.mExtras;
-        }
-    }
-
     @Override
     public void run() {
         Log.i(LOGTAG, "preparing to run Gecko");
 
         Looper.prepare();
         GeckoThread.msgQueue = Looper.myQueue();
         ThreadUtils.sGeckoThread = this;
         ThreadUtils.sGeckoHandler = new Handler();
@@ -396,17 +379,17 @@ public class GeckoThread extends Thread 
                 idleMsg.obj = geckoHandler;
                 geckoHandler.sendMessageAtFrontOfQueue(idleMsg);
                 // Keep this IdleHandler
                 return true;
             }
         };
         Looper.myQueue().addIdleHandler(idleHandler);
 
-        initGeckoEnvironment(mExtras);
+        initGeckoEnvironment();
 
         if ((mFlags & FLAG_PRELOAD_CHILD) != 0) {
             ThreadUtils.postToBackgroundThread(new Runnable() {
                 @Override
                 public void run() {
                     // Preload the content ("tab") child process.
                     GeckoProcessManager.getInstance().preload("tab");
                 }
@@ -434,20 +417,17 @@ public class GeckoThread extends Thread 
 
         Log.w(LOGTAG, "zerdatime " + SystemClock.elapsedRealtime() + " - runGecko");
 
         if ((mFlags & FLAG_DEBUGGING) != 0) {
             Log.i(LOGTAG, "RunGecko - args = " + TextUtils.join(" ", args));
         }
 
         // And go.
-        GeckoLoader.nativeRun(args,
-                              mExtras.getInt(EXTRA_IPC_FD, -1),
-                              mExtras.getInt(EXTRA_CRASH_FD, -1),
-                              mExtras.getInt(EXTRA_CRASH_ANNOTATION_FD, -1));
+        GeckoLoader.nativeRun(args, mCrashFileDescriptor, mIPCFileDescriptor, mCrashAnnotationFileDescriptor);
 
         // And... we're done.
         final boolean restarting = isState(State.RESTARTING);
         setState(State.EXITED);
 
         final GeckoBundle data = new GeckoBundle(1);
         data.putBoolean("restart", restarting);
         EventDispatcher.getInstance().dispatch("Gecko:Exited", data);
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java
@@ -10,35 +10,36 @@ import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.util.Locale;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
 import android.content.Context;
 import android.content.Intent;
 import android.os.Build;
-import android.os.Bundle;
 import android.os.Environment;
 import java.util.ArrayList;
 import android.util.Log;
 
 import org.mozilla.gecko.annotation.JNITarget;
 import org.mozilla.gecko.annotation.RobocopTarget;
 import org.mozilla.geckoview.BuildConfig;
 
 public final class GeckoLoader {
     private static final String LOGTAG = "GeckoLoader";
 
+    private static volatile SafeIntent sIntent;
     private static File sCacheFile;
     private static File sGREDir;
 
     /* Synchronized on GeckoLoader.class. */
     private static boolean sSQLiteLibsLoaded;
     private static boolean sNSSLibsLoaded;
     private static boolean sMozGlueLoaded;
+    private static String[] sEnvList;
 
     private GeckoLoader() {
         // prevent instantiation
     }
 
     public static File getCacheDir(Context context) {
         if (sCacheFile == null) {
             sCacheFile = context.getCacheDir();
@@ -85,28 +86,45 @@ public final class GeckoLoader {
         // check if the old tmp dir is there
         File oldDir = new File(tmpDir.getParentFile(), "app_tmp");
         if (oldDir.exists()) {
             delTree(oldDir);
         }
         return tmpDir;
     }
 
-    public static void setupGeckoEnvironment(final Context context, final String profilePath,
-                                             final Bundle extras) {
+    public static void setLastIntent(SafeIntent intent) {
+        sIntent = intent;
+    }
+
+    public static void addEnvironmentToIntent(Intent intent) {
+        if (sEnvList != null) {
+            for (int ix = 0; ix < sEnvList.length; ix++) {
+                intent.putExtra("env" + ix, sEnvList[ix]);
+            }
+        }
+    }
+
+    public static void setupGeckoEnvironment(Context context, String profilePath) {
         // if we have an intent (we're being launched by an activity)
         // read in any environmental variables from it here
-        if (extras != null) {
-            String env = extras.getString("env0");
+        final SafeIntent intent = sIntent;
+        if (intent != null) {
+            final ArrayList<String> envList = new ArrayList<String>();
+            String env = intent.getStringExtra("env0");
             Log.d(LOGTAG, "Gecko environment env0: " + env);
             for (int c = 1; env != null; c++) {
+                envList.add(env);
                 putenv(env);
-                env = extras.getString("env" + c);
+                env = intent.getStringExtra("env" + c);
                 Log.d(LOGTAG, "env" + c + ": " + env);
             }
+            if (envList.size() > 0) {
+              sEnvList = envList.toArray(new String[envList.size()]);
+            }
         }
 
         try {
             final File dataDir = new File(context.getApplicationInfo().dataDir);
             putenv("MOZ_ANDROID_DATA_DIR=" + dataDir.getCanonicalPath());
         } catch (final java.io.IOException e) {
             Log.e(LOGTAG, "Failed to resolve app data directory");
         }
@@ -137,16 +155,19 @@ public final class GeckoLoader {
             android.os.UserManager um = (android.os.UserManager)context.getSystemService(Context.USER_SERVICE);
             if (um != null) {
                 putenv("MOZ_ANDROID_USER_SERIAL_NUMBER=" + um.getSerialNumberForUser(android.os.Process.myUserHandle()));
             } else {
                 Log.d(LOGTAG, "Unable to obtain user manager service on a device with SDK version " + Build.VERSION.SDK_INT);
             }
         }
         setupLocaleEnvironment();
+
+        // We don't need this any more.
+        sIntent = null;
     }
 
     private static void loadLibsSetupLocked(Context context) {
         // The package data lib directory isn't placed in ld.so's
         // search path, so we have to manually load libraries that
         // libxul will depend on.  Not ideal.
 
         File cacheFile = getCacheDir(context);
@@ -468,15 +489,15 @@ public final class GeckoLoader {
         }
     }
 
     // These methods are implemented in mozglue/android/nsGeckoUtils.cpp
     private static native void putenv(String map);
     public static native boolean verifyCRCs(String apkName);
 
     // These methods are implemented in mozglue/android/APKOpen.cpp
-    public static native void nativeRun(String[] args, int ipcFd, int crashFd, int crashAnnotationFd);
+    public static native void nativeRun(String[] args, int crashFd, int ipcFd, int crashAnnotationFd);
     private static native void loadGeckoLibsNative(String apkName);
     private static native void loadSQLiteLibsNative(String apkName);
     private static native void loadNSSLibsNative(String apkName);
     public static native boolean neonCompatible();
     public static native void suppressCrashDialog();
 }
--- 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,17 +5,16 @@
  */
 
 // 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.
@@ -37,28 +36,16 @@ 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);
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/process/GeckoProcessManager.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/process/GeckoProcessManager.java
@@ -1,25 +1,24 @@
 /* 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.process;
 
 import org.mozilla.gecko.GeckoAppShell;
-import org.mozilla.gecko.GeckoThread;
 import org.mozilla.gecko.IGeckoEditableParent;
 import org.mozilla.gecko.annotation.WrapForJNI;
+import org.mozilla.gecko.mozglue.GeckoLoader;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.os.Bundle;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.support.v4.util.SimpleArrayMap;
 import android.util.Log;
 
@@ -70,16 +69,17 @@ public final class GeckoProcessManager e
             if (mChild != null) {
                 return mChild;
             }
 
             final Context context = GeckoAppShell.getApplicationContext();
             final Intent intent = new Intent();
             intent.setClassName(context,
                                 GeckoServiceChildProcess.class.getName() + '$' + mType);
+            GeckoLoader.addEnvironmentToIntent(intent);
 
             if (context.bindService(intent, this, Context.BIND_AUTO_CREATE)) {
                 waitForChildLocked();
                 if (mChild != null) {
                     return mChild;
                 }
             }
 
@@ -163,63 +163,59 @@ public final class GeckoProcessManager e
             final ChildConnection connection = getConnection(type);
             connection.bind();
             connection.getPid();
         }
     }
 
     @WrapForJNI
     private static int start(final String type, final String[] args,
-                             final int ipcFd, final int crashFd,
+                             final int crashFd, final int ipcFd,
                              final int crashAnnotationFd) {
-        return INSTANCE.start(type, args, ipcFd, crashFd, crashAnnotationFd, /* retry */ false);
+        return INSTANCE.start(type, args, crashFd, ipcFd, crashAnnotationFd, /* retry */ false);
     }
 
-    private int start(final String type, final String[] args, final int ipcFd,
-                      final int crashFd, final int crashAnnotationFd,
+    private int start(final String type, final String[] args, final int crashFd,
+                      final int ipcFd, final int crashAnnotationFd,
                       final boolean retry) {
         final ChildConnection connection = getConnection(type);
         final IChildProcess child = connection.bind();
         if (child == null) {
             return 0;
         }
 
-        final Bundle extras = GeckoThread.getActiveExtras();
+        final ParcelFileDescriptor crashPfd;
         final ParcelFileDescriptor ipcPfd;
-        final ParcelFileDescriptor crashPfd;
         final ParcelFileDescriptor crashAnnotationPfd;
         try {
+            crashPfd = (crashFd >= 0) ? ParcelFileDescriptor.fromFd(crashFd) : null;
             ipcPfd = ParcelFileDescriptor.fromFd(ipcFd);
-            crashPfd = (crashFd >= 0) ? ParcelFileDescriptor.fromFd(crashFd) : null;
             crashAnnotationPfd = (crashAnnotationFd >= 0) ? ParcelFileDescriptor.fromFd(crashAnnotationFd) : null;
         } catch (final IOException e) {
             Log.e(LOGTAG, "Cannot create fd for " + type, e);
             return 0;
         }
 
         boolean started = false;
         try {
-            started = child.start(this, args, extras, ipcPfd, crashPfd, crashAnnotationPfd);
+            started = child.start(this, args, crashPfd, ipcPfd, crashAnnotationPfd);
         } catch (final RemoteException e) {
         }
 
         if (!started) {
             if (retry) {
                 Log.e(LOGTAG, "Cannot restart child " + type);
                 return 0;
             }
             Log.w(LOGTAG, "Attempting to kill running child " + type);
             connection.unbind();
-            return start(type, args, ipcFd, crashFd, crashAnnotationFd, /* retry */ true);
+            return start(type, args, crashFd, ipcFd, crashAnnotationFd, /* retry */ true);
         }
 
         try {
-            if (crashAnnotationPfd != null) {
-                crashAnnotationPfd.close();
-            }
             if (crashPfd != null) {
                 crashPfd.close();
             }
             ipcPfd.close();
         } catch (final IOException e) {
         }
 
         return connection.getPid();
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/process/GeckoServiceChildProcess.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/process/GeckoServiceChildProcess.java
@@ -11,17 +11,16 @@ import org.mozilla.gecko.IGeckoEditableP
 import org.mozilla.gecko.mozglue.GeckoLoader;
 import org.mozilla.gecko.GeckoThread;
 import org.mozilla.gecko.mozglue.SafeIntent;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import android.app.Service;
 import android.content.Intent;
 import android.os.Binder;
-import android.os.Bundle;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.RemoteException;
 import android.util.Log;
 
 public class GeckoServiceChildProcess extends Service {
 
@@ -57,49 +56,47 @@ public class GeckoServiceChildProcess ex
         @Override
         public int getPid() {
             return Process.myPid();
         }
 
         @Override
         public boolean start(final IProcessManager procMan,
                              final String[] args,
-                             final Bundle extras,
+                             final ParcelFileDescriptor crashReporterPfd,
                              final ParcelFileDescriptor ipcPfd,
-                             final ParcelFileDescriptor crashReporterPfd,
                              final ParcelFileDescriptor crashAnnotationPfd) {
             synchronized (GeckoServiceChildProcess.class) {
                 if (sProcessManager != null) {
                     Log.e(LOGTAG, "Child process already started");
                     return false;
                 }
                 sProcessManager = procMan;
             }
 
-            final int ipcFd = ipcPfd.detachFd();
             final int crashReporterFd = crashReporterPfd != null ?
                                         crashReporterPfd.detachFd() : -1;
-            final int crashAnnotationFd = crashAnnotationPfd != null ?
-                                          crashAnnotationPfd.detachFd() : -1;
+            final int ipcFd = ipcPfd != null ? ipcPfd.detachFd() : -1;
+            final int crashAnnotationFd = crashAnnotationPfd != null ? crashAnnotationPfd.detachFd() : -1;
 
             ThreadUtils.postToUiThread(new Runnable() {
                 @Override
                 public void run() {
-                    if (GeckoThread.initChildProcess(args, extras, ipcFd, crashReporterFd,
-                                                     crashAnnotationFd)) {
+                    if (GeckoThread.initChildProcess(args, crashReporterFd, ipcFd, crashAnnotationFd)) {
                         GeckoThread.launch();
                     }
                 }
             });
             return true;
         }
     };
 
     @Override
     public IBinder onBind(final Intent intent) {
+        GeckoLoader.setLastIntent(new SafeIntent(intent));
         GeckoThread.launch(); // Preload Gecko.
         return mBinder;
     }
 
     @Override
     public boolean onUnbind(Intent intent) {
         Log.i(LOGTAG, "Service has been unbound. Stopping.");
         Process.killProcess(Process.myPid());
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
@@ -26,23 +26,21 @@ import org.mozilla.gecko.util.GeckoBundl
 import org.mozilla.gecko.util.ThreadUtils;
 
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Binder;
-import android.os.Bundle;
 import android.os.IBinder;
 import android.os.IInterface;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
-import android.support.annotation.Nullable;
 import android.support.annotation.NonNull;
 import android.util.Log;
 
 public class GeckoSession extends LayerSession
                           implements Parcelable {
     private static final String LOGTAG = "GeckoSession";
     private static final boolean DEBUG = false;
 
@@ -542,73 +540,62 @@ public class GeckoSession extends LayerS
         }
     };
 
     /**
      * Preload GeckoSession by starting Gecko in the background, if Gecko is not already running.
      *
      * @param context Activity or Application Context for starting GeckoSession.
      */
-    public static void preload(final @NonNull Context context) {
-        preload(context, /* geckoArgs */ null,
-                /* extras */ null, /* multiprocess */ false);
+    public static void preload(final Context context) {
+        preload(context, /* geckoArgs */ null, /* multiprocess */ false);
     }
 
     /**
      * Preload GeckoSession by starting Gecko with the specified arguments in the background,
      * if Gecko is not already running.
      *
      * @param context Activity or Application Context for starting GeckoSession.
      * @param geckoArgs Arguments to be passed to Gecko, if Gecko is not already running.
      * @param multiprocess True if child process in multiprocess mode should be preloaded.
      */
-    public static void preload(final @NonNull Context context,
-                               final @Nullable String[] geckoArgs,
-                               final @Nullable Bundle extras,
+    public static void preload(final Context context, final String geckoArgs,
                                final boolean multiprocess) {
         final Context appContext = context.getApplicationContext();
-        if (!appContext.equals(GeckoAppShell.getApplicationContext())) {
+        if (GeckoAppShell.getApplicationContext() == null) {
             GeckoAppShell.setApplicationContext(appContext);
         }
 
-        if (GeckoThread.isLaunched()) {
-            return;
-        }
-
         final int flags = multiprocess ? GeckoThread.FLAG_PRELOAD_CHILD : 0;
-        if (GeckoThread.initMainProcess(/* profile */ null, geckoArgs, extras, flags)) {
+        if (GeckoThread.initMainProcess(/* profile */ null, geckoArgs, flags)) {
             GeckoThread.launch();
         }
     }
 
     public boolean isOpen() {
         return mWindow != null;
     }
 
     /* package */ boolean isReady() {
         return mNativeQueue.isReady();
     }
 
-    public void openWindow(final @Nullable Context appContext) {
+    public void openWindow(final Context appContext) {
         ThreadUtils.assertOnUiThread();
 
         if (isOpen()) {
             throw new IllegalStateException("Session is open");
         }
 
-        if (appContext != null) {
+        if (!GeckoThread.isLaunched()) {
             final boolean multiprocess =
                     mSettings.getBoolean(GeckoSessionSettings.USE_MULTIPROCESS);
-            preload(appContext, /* geckoArgs */ null, /* extras */ null, multiprocess);
+            preload(appContext, /* geckoArgs */ null, multiprocess);
         }
 
-        openWindow();
-    }
-
-    private void openWindow() {
         final String chromeUri = mSettings.getString(GeckoSessionSettings.CHROME_URI);
         final int screenId = mSettings.getInt(GeckoSessionSettings.SCREEN_ID);
         final boolean isPrivate = mSettings.getBoolean(GeckoSessionSettings.USE_PRIVATE_MODE);
 
         mWindow = new Window(mNativeQueue);
 
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
             Window.open(mWindow, mCompositor, mEventDispatcher,
--- a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
+++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
@@ -43,28 +43,35 @@ public class GeckoViewActivity extends A
     private GeckoView mGeckoView;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         Log.i(LOGTAG, "zerdatime " + SystemClock.elapsedRealtime() +
               " - application start");
 
-        final String[] geckoArgs;
+        String geckoArgs = null;
+        final String intentArgs = getIntent().getStringExtra("args");
 
         if (BuildConfig.DEBUG) {
             // In debug builds, we want to load JavaScript resources fresh with each build.
-            geckoArgs = new String[] { "-purgecaches" };
-        } else {
-            geckoArgs = null;
+            geckoArgs = "-purgecaches";
+        }
+
+        if (!TextUtils.isEmpty(intentArgs)) {
+            if (geckoArgs == null) {
+                geckoArgs = intentArgs;
+            } else {
+                geckoArgs += " " + intentArgs;
+            }
         }
 
         final boolean useMultiprocess = getIntent().getBooleanExtra(USE_MULTIPROCESS_EXTRA,
                                                                     true);
-        GeckoSession.preload(this, geckoArgs, getIntent().getExtras(), useMultiprocess);
+        GeckoSession.preload(this, geckoArgs, useMultiprocess);
 
         setContentView(R.layout.geckoview_activity);
 
         mGeckoView = (GeckoView) findViewById(R.id.gecko_view);
         mGeckoSession = new GeckoSession();
         mGeckoView.setSession(mGeckoSession);
 
         mGeckoSession.setContentDelegate(new MyGeckoViewContent());
--- a/mozglue/android/APKOpen.cpp
+++ b/mozglue/android/APKOpen.cpp
@@ -387,32 +387,32 @@ FreeArgv(char** argv, int argc)
   for (int ix=0; ix < argc; ix++) {
     // String was allocated with strndup, so need to use free to deallocate.
     free(argv[ix]);
   }
   delete[](argv);
 }
 
 extern "C" APKOPEN_EXPORT void MOZ_JNICALL
-Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(JNIEnv *jenv, jclass jc, jobjectArray jargs, int ipcFd, int crashFd, int crashAnnotationFd)
+Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(JNIEnv *jenv, jclass jc, jobjectArray jargs, int crashFd, int ipcFd, int crashAnnotationFd)
 {
   int argc = 0;
   char** argv = CreateArgvFromObjectArray(jenv, jargs, &argc);
 
   if (ipcFd < 0) {
     if (gBootstrap == nullptr) {
       FreeArgv(argv, argc);
       return;
     }
 
     ElfLoader::Singleton.ExpectShutdown(false);
     gBootstrap->GeckoStart(jenv, argv, argc, sAppData);
     ElfLoader::Singleton.ExpectShutdown(true);
   } else {
-    gBootstrap->XRE_SetAndroidChildFds(jenv, ipcFd, crashFd, crashAnnotationFd);
+    gBootstrap->XRE_SetAndroidChildFds(jenv, crashFd, ipcFd, crashAnnotationFd);
     gBootstrap->XRE_SetProcessType(argv[argc - 1]);
 
     XREChildData childData;
     gBootstrap->XRE_InitChildProcess(argc - 1, argv, &childData);
   }
 
   gBootstrap.reset();
   FreeArgv(argv, argc);
--- a/toolkit/xre/Bootstrap.cpp
+++ b/toolkit/xre/Bootstrap.cpp
@@ -73,18 +73,18 @@ public:
     ::XRE_EnableSameExecutableForContentProc();
   }
 
 #ifdef MOZ_WIDGET_ANDROID
   virtual void GeckoStart(JNIEnv* aEnv, char** argv, int argc, const StaticXREAppData& aAppData) override {
     ::GeckoStart(aEnv, argv, argc, aAppData);
   }
 
-  virtual void XRE_SetAndroidChildFds(JNIEnv* aEnv, int aIPCFd, int aCrashFd, int aCrashAnnotationFd) override {
-    ::XRE_SetAndroidChildFds(aEnv, aIPCFd, aCrashFd, aCrashAnnotationFd);
+  virtual void XRE_SetAndroidChildFds(JNIEnv* aEnv, int aCrashFd, int aIPCFd, int aCrashAnnotationFd) override {
+    ::XRE_SetAndroidChildFds(aEnv, aCrashFd, aIPCFd, aCrashAnnotationFd);
   }
 #endif
 
 #ifdef LIBFUZZER
   virtual void XRE_LibFuzzerSetDriver(LibFuzzerDriver aDriver) override {
     ::XRE_LibFuzzerSetDriver(aDriver);
   }
 #endif
--- a/toolkit/xre/Bootstrap.h
+++ b/toolkit/xre/Bootstrap.h
@@ -108,17 +108,17 @@ public:
 
   virtual nsresult XRE_InitChildProcess(int argc, char* argv[], const XREChildData* aChildData) = 0;
 
   virtual void XRE_EnableSameExecutableForContentProc() = 0;
 
 #ifdef MOZ_WIDGET_ANDROID
   virtual void GeckoStart(JNIEnv* aEnv, char** argv, int argc, const StaticXREAppData& aAppData) = 0;
 
-  virtual void XRE_SetAndroidChildFds(JNIEnv* aEnv, int aIPCFd, int aCrashFd, int aCrashAnnotationFd) = 0;
+  virtual void XRE_SetAndroidChildFds(JNIEnv* aEnv, int aCrashFd, int aIPCFd, int aCrashAnnotationFd) = 0;
 #endif
 
 #ifdef LIBFUZZER
   virtual void XRE_LibFuzzerSetDriver(LibFuzzerDriver aDriver) = 0;
 #endif
 
 #ifdef MOZ_IPDL_TESTS
   virtual int XRE_RunIPDLTest(int argc, char **argv) = 0;
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -238,22 +238,22 @@ XRE_ChildProcessTypeToString(GeckoProces
 namespace mozilla {
 namespace startup {
 GeckoProcessType sChildProcessType = GeckoProcessType_Default;
 } // namespace startup
 } // namespace mozilla
 
 #if defined(MOZ_WIDGET_ANDROID)
 void
-XRE_SetAndroidChildFds (JNIEnv* env, int ipcFd, int crashFd, int crashAnnotationFd)
+XRE_SetAndroidChildFds (JNIEnv* env, int crashFd, int ipcFd, int crashAnnotationFd)
 {
   mozilla::jni::SetGeckoThreadEnv(env);
-  IPC::Channel::SetClientChannelFd(ipcFd);
   CrashReporter::SetNotificationPipeForChild(crashFd);
   CrashReporter::SetCrashAnnotationPipeForChild(crashAnnotationFd);
+  IPC::Channel::SetClientChannelFd(ipcFd);
 }
 #endif // defined(MOZ_WIDGET_ANDROID)
 
 void
 XRE_SetProcessType(const char* aProcessTypeString)
 {
   static bool called = false;
   if (called) {
--- a/xpcom/build/nsXULAppAPI.h
+++ b/xpcom/build/nsXULAppAPI.h
@@ -393,17 +393,17 @@ static_assert(MOZ_ARRAY_LENGTH(kGeckoPro
               GeckoProcessType_End,
               "Array length mismatch");
 
 XRE_API(const char*,
         XRE_ChildProcessTypeToString, (GeckoProcessType aProcessType))
 
 #if defined(MOZ_WIDGET_ANDROID)
 XRE_API(void,
-        XRE_SetAndroidChildFds, (JNIEnv* env, int ipcFd, int crashFd, int crashAnnotationFd))
+        XRE_SetAndroidChildFds, (JNIEnv* env, int crashFd, int ipcFd, int crashAnnotationFd))
 #endif // defined(MOZ_WIDGET_ANDROID)
 
 XRE_API(void,
         XRE_SetProcessType, (const char* aProcessTypeString))
 
 // Used in the "master" parent process hosting the crash server
 XRE_API(bool,
         XRE_TakeMinidumpForChild, (uint32_t aChildPid, nsIFile** aDump,