Bug 1442255 - 2. Replace GeckoThread fields with extras bundle; r=esawin
☠☠ backed out by b1dc3a24a077 ☠ ☠
authorJim Chen <nchen@mozilla.com>
Tue, 06 Mar 2018 00:04:55 -0500
changeset 461721 08f906f3a0c836d333699f528f70a6b86a69f5eb
parent 461720 d7a43e59a1b4ea7c294e7645c4f77d798fe7be67
child 461722 c3305648ad30458a5eb098c6f4fdea5358d339a0
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersesawin
bugs1442255
milestone60.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 1442255 - 2. Replace GeckoThread fields with extras bundle; r=esawin Introduce an extras bundle in GeckoThread, which we use to store things such as extra main process arguments and child process FDs. Also use the extras bundle to store environment variables to be passed to GeckoLoader. MozReview-Commit-ID: tRlBaAXxVa
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java
--- 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,21 +11,23 @@ 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.Locale;
@@ -115,77 +117,76 @@ 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 GeckoProfile mProfile;
-    private String mExtraArgs;
-    private int mFlags;
+    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";
 
-    // Child process parameters
-    private int mCrashFileDescriptor = -1;
-    private int mIPCFileDescriptor = -1;
-    private int mCrashAnnotationFileDescriptor = -1;
+    private boolean mInitialized;
+    private GeckoProfile mProfile;
+    private String[] mArgs;
+    private Bundle mExtras;
+    private int mFlags;
 
     GeckoThread() {
         setName("Gecko");
     }
 
     @WrapForJNI
     private static boolean isChildProcess() {
-        return INSTANCE.mIPCFileDescriptor != -1;
+        return INSTANCE.mExtras.getInt(EXTRA_IPC_FD, -1) != -1;
     }
 
     private synchronized boolean init(final GeckoProfile profile, final String[] args,
-                                      final String extraArgs, final int flags,
-                                      final int crashFd, final int ipcFd,
+                                      final Bundle extras, final int flags,
+                                      final int ipcFd, final int crashFd,
                                       final int crashAnnotationFd) {
         ThreadUtils.assertOnUiThread();
         uiThreadId = android.os.Process.myTid();
 
         if (mInitialized) {
             return false;
         }
 
         mProfile = profile;
         mArgs = args;
-        mExtraArgs = extraArgs;
         mFlags = flags;
-        mCrashFileDescriptor = crashFd;
-        mIPCFileDescriptor = ipcFd;
-        mCrashAnnotationFileDescriptor = crashAnnotationFd;
+
+        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);
 
         mInitialized = true;
         notifyAll();
         return true;
     }
 
-    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 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 initChildProcess(final String[] args, final int crashFd,
-                                           final int ipcFd,
+    public static boolean initChildProcess(final String[] args, final Bundle extras,
+                                           final int ipcFd, final int crashFd,
                                            final int crashAnnotationFd) {
-        return INSTANCE.init(/* profile */ null, args, /* extraArgs */ null,
-                                 /* flags */ 0, crashFd, ipcFd, crashAnnotationFd);
+        return INSTANCE.init(/* profile */ null, args, extras, /* flags */ 0,
+                             ipcFd, crashFd, crashAnnotationFd);
     }
 
     private static boolean canUseProfile(final Context context, final GeckoProfile profile,
                                          final String profileName, final File profileDir) {
         if (profileDir != null && !profileDir.isDirectory()) {
             return false;
         }
 
@@ -210,17 +211,18 @@ 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 String[] args,
+                                                     final Bundle extras) {
         if (profileName == null) {
             throw new IllegalArgumentException("Null profile name");
         }
 
         final Context context = GeckoAppShell.getApplicationContext();
         final GeckoProfile profile = getActiveProfile();
 
         if (!canUseProfile(context, profile, profileName, profileDir)) {
@@ -229,18 +231,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, /* flags */ 0);
+        return initMainProcess(GeckoProfile.get(context, profileName, profileDir), args,
+                               extras, /* flags */ 0);
     }
 
     public static boolean launch() {
         ThreadUtils.assertOnUiThread();
 
         if (checkAndSetState(State.INITIAL, State.LAUNCHED)) {
             INSTANCE.start();
             return true;
@@ -259,33 +261,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() {
+    private static void initGeckoEnvironment(final Bundle extras) {
         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());
+        GeckoLoader.setupGeckoEnvironment(context, context.getFilesDir().getPath(), extras);
 
         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);
         }
@@ -318,18 +320,19 @@ 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 (mExtraArgs != null) {
-            final StringTokenizer st = new StringTokenizer(mExtraArgs);
+        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()) {
                         st.nextToken();
                     }
                     continue;
@@ -351,21 +354,30 @@ 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, mExtraArgs);
+            mProfile = GeckoProfile.initFromArgs(context, mExtras.getString(EXTRA_ARGS, null));
         }
         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();
@@ -379,17 +391,17 @@ public class GeckoThread extends Thread 
                 idleMsg.obj = geckoHandler;
                 geckoHandler.sendMessageAtFrontOfQueue(idleMsg);
                 // Keep this IdleHandler
                 return true;
             }
         };
         Looper.myQueue().addIdleHandler(idleHandler);
 
-        initGeckoEnvironment();
+        initGeckoEnvironment(mExtras);
 
         if ((mFlags & FLAG_PRELOAD_CHILD) != 0) {
             ThreadUtils.postToBackgroundThread(new Runnable() {
                 @Override
                 public void run() {
                     // Preload the content ("tab") child process.
                     GeckoProcessManager.getInstance().preload("tab");
                 }
@@ -417,17 +429,19 @@ 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, mCrashFileDescriptor, mIPCFileDescriptor, mCrashAnnotationFileDescriptor);
+        GeckoLoader.nativeRun(args, mExtras.getInt(EXTRA_CRASH_FD, -1),
+                              mExtras.getInt(EXTRA_IPC_FD, -1),
+                              mExtras.getInt(EXTRA_CRASH_ANNOTATION_FD, -1));
 
         // 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);