From afb248e2fa3d4af9c23d6fd8e3d1786ce7051870 Mon Sep 17 00:00:00 2001 From: Jim Chen Date: Thu, 13 Aug 2015 00:53:39 -0400 Subject: [PATCH] Bug 1189995 - Move GeckoAppShell.runGecko to GeckoThread; r=esawin GeckoAppShell.runGecko really should be in GeckoThread because GeckoThread already takes care of most of the preparation when running Gecko. This patch merges runGecko into GeckoThread.run, but split the argument-building code into its own method. --- mobile/android/base/GeckoAppShell.java | 51 ---------------- mobile/android/base/GeckoThread.java | 80 ++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 63 deletions(-) diff --git a/mobile/android/base/GeckoAppShell.java b/mobile/android/base/GeckoAppShell.java index 060464d66b73..eb28161e5d74 100644 --- a/mobile/android/base/GeckoAppShell.java +++ b/mobile/android/base/GeckoAppShell.java @@ -41,7 +41,6 @@ import org.mozilla.gecko.gfx.BitmapUtils; import org.mozilla.gecko.gfx.LayerView; import org.mozilla.gecko.gfx.PanZoomController; import org.mozilla.gecko.mozglue.ContextUtils; -import org.mozilla.gecko.mozglue.GeckoLoader; import org.mozilla.gecko.overlays.ui.ShareDialog; import org.mozilla.gecko.prompts.PromptService; import org.mozilla.gecko.util.EventCallback; @@ -339,56 +338,6 @@ public class GeckoAppShell return sLayerView; } - public static void runGecko(String apkPath, String args, String url, String type) { - // Preparation for pumpMessageLoop() - MessageQueue.IdleHandler idleHandler = new MessageQueue.IdleHandler() { - @Override public boolean queueIdle() { - final Handler geckoHandler = ThreadUtils.sGeckoHandler; - Message idleMsg = Message.obtain(geckoHandler); - // Use |Message.obj == GeckoHandler| to identify our "queue is empty" message - idleMsg.obj = geckoHandler; - geckoHandler.sendMessageAtFrontOfQueue(idleMsg); - // Keep this IdleHandler - return true; - } - }; - Looper.myQueue().addIdleHandler(idleHandler); - - // Initialize AndroidBridge. - nativeInit(GeckoAppShell.class.getClassLoader(), Looper.myQueue()); - - // First argument is the .apk path - String combinedArgs = apkPath + " -greomni " + apkPath; - if (args != null) - combinedArgs += " " + args; - if (url != null) - combinedArgs += " -url " + url; - if (type != null) - combinedArgs += " " + type; - - // 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. - if (!AppConstants.MOZILLA_OFFICIAL) { - Log.w(LOGTAG, "STARTUP PERFORMANCE WARNING: un-official build: purging the " + - "startup (JavaScript) caches."); - combinedArgs += " -purgecaches"; - } - - DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); - combinedArgs += " -width " + metrics.widthPixels + " -height " + metrics.heightPixels; - - if (!AppConstants.MOZILLA_OFFICIAL) { - Log.d(LOGTAG, "GeckoLoader.nativeRun " + combinedArgs); - } - // and go - GeckoLoader.nativeRun(combinedArgs); - - // Remove pumpMessageLoop() idle handler - Looper.myQueue().removeIdleHandler(idleHandler); - } - /** * If the Gecko thread is running, immediately dispatches the event to * Gecko. diff --git a/mobile/android/base/GeckoThread.java b/mobile/android/base/GeckoThread.java index 1a4ba3da9da4..9aec53ea0a13 100644 --- a/mobile/android/base/GeckoThread.java +++ b/mobile/android/base/GeckoThread.java @@ -18,7 +18,10 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.os.Handler; import android.os.Looper; +import android.os.Message; +import android.os.MessageQueue; import android.os.SystemClock; +import android.util.DisplayMetrics; import android.util.Log; import java.io.IOException; @@ -225,13 +228,12 @@ public class GeckoThread extends Thread implements GeckoEventListener { } } - private String initGeckoEnvironment() { - final Locale locale = Locale.getDefault(); - + private static String initGeckoEnvironment() { final Context context = GeckoAppShell.getContext(); 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; @@ -241,7 +243,6 @@ public class GeckoThread extends Thread implements GeckoEventListener { res.updateConfiguration(config, null); } - String resourcePath = ""; String[] pluginDirs = null; try { pluginDirs = GeckoAppShell.getPluginDirectories(); @@ -249,7 +250,7 @@ public class GeckoThread extends Thread implements GeckoEventListener { Log.w(LOGTAG, "Caught exception getting plugin dirs.", e); } - resourcePath = context.getPackageResourcePath(); + final String resourcePath = context.getPackageResourcePath(); GeckoLoader.setupGeckoEnvironment(context, pluginDirs, context.getFilesDir().getPath()); GeckoLoader.loadSQLiteLibs(context, resourcePath); @@ -260,14 +261,14 @@ public class GeckoThread extends Thread implements GeckoEventListener { return resourcePath; } - private String getTypeFromAction(String action) { + private static String getTypeFromAction(String action) { if (GeckoApp.ACTION_HOMESCREEN_SHORTCUT.equals(action)) { return "-bookmark"; } return null; } - private String addCustomProfileArg(String args) { + private static String addCustomProfileArg(String args) { String profileArg = ""; String guestArg = ""; if (GeckoAppShell.getGeckoInterface() != null) { @@ -293,12 +294,63 @@ public class GeckoThread extends Thread implements GeckoEventListener { return (args != null ? args : "") + profileArg + guestArg; } + private String getGeckoArgs(final String apkPath) { + // First argument is the .apk path + final StringBuilder args = new StringBuilder(apkPath); + args.append(" -greomni ").append(apkPath); + + final String userArgs = addCustomProfileArg(mArgs); + if (userArgs != null) { + args.append(' ').append(userArgs); + } + + if (mUri != null) { + args.append(" -url ").append(mUri); + } + + final String type = getTypeFromAction(mAction); + if (type != null) { + args.append(" ").append(type); + } + + // 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. + if (!AppConstants.MOZILLA_OFFICIAL) { + Log.w(LOGTAG, "STARTUP PERFORMANCE WARNING: un-official build: purging the " + + "startup (JavaScript) caches."); + args.append(" -purgecaches"); + } + + final DisplayMetrics metrics + = GeckoAppShell.getContext().getResources().getDisplayMetrics(); + args.append(" -width ").append(metrics.widthPixels) + .append(" -height ").append(metrics.heightPixels); + + return args.toString(); + } + @Override public void run() { Looper.prepare(); ThreadUtils.sGeckoThread = this; ThreadUtils.sGeckoHandler = new Handler(); + // Preparation for pumpMessageLoop() + final MessageQueue.IdleHandler idleHandler = new MessageQueue.IdleHandler() { + @Override public boolean queueIdle() { + final Handler geckoHandler = ThreadUtils.sGeckoHandler; + Message idleMsg = Message.obtain(geckoHandler); + // Use |Message.obj == GeckoHandler| to identify our "queue is empty" message + idleMsg.obj = geckoHandler; + geckoHandler.sendMessageAtFrontOfQueue(idleMsg); + // Keep this IdleHandler + return true; + } + }; + Looper.myQueue().addIdleHandler(idleHandler); + if (mDebugging) { try { Thread.sleep(5 * 1000 /* 5 seconds */); @@ -306,7 +358,7 @@ public class GeckoThread extends Thread implements GeckoEventListener { } } - String path = initGeckoEnvironment(); + final String args = getGeckoArgs(initGeckoEnvironment()); // This can only happen after the call to initGeckoEnvironment // above, because otherwise the JNI code hasn't been loaded yet. @@ -318,14 +370,15 @@ public class GeckoThread extends Thread implements GeckoEventListener { Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - runGecko"); - String args = addCustomProfileArg(mArgs); - String type = getTypeFromAction(mAction); + // Initialize AndroidBridge. + GeckoAppShell.nativeInit(GeckoThread.class.getClassLoader(), Looper.myQueue()); if (!AppConstants.MOZILLA_OFFICIAL) { Log.i(LOGTAG, "RunGecko - args = " + args); } - // and then fire us up - GeckoAppShell.runGecko(path, args, mUri, type); + + // And go. + GeckoLoader.nativeRun(args); // And... we're done. setState(State.EXITED); @@ -337,6 +390,9 @@ public class GeckoThread extends Thread implements GeckoEventListener { } catch (final JSONException e) { Log.e(LOGTAG, "unable to dispatch event", e); } + + // Remove pumpMessageLoop() idle handler + Looper.myQueue().removeIdleHandler(idleHandler); } public static void addPendingEvent(final GeckoEvent e) {