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
--- 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);