зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1567341 - Allow geckoview.test to run xpcshell. r=esawin
This commit adds a new command line option |-xpcshell| that, when passed, will run an xpcshell instead of launching a full Gecko instance. This command line option is restricted to org.mozilla.geckoview.test for now, as it's really hard to use and not really a usecase outside mozilla. We can revisit this if there's interest. Differential Revision: https://phabricator.services.mozilla.com/D106211
This commit is contained in:
Родитель
bc9ab239dc
Коммит
34624a6abf
|
@ -154,6 +154,8 @@ public class GeckoThread extends Thread {
|
|||
public Map<String, Object> prefs;
|
||||
public String userSerialNumber;
|
||||
|
||||
public boolean xpcshell;
|
||||
public String outFilePath;
|
||||
public int prefsFd;
|
||||
public int prefMapFd;
|
||||
public int ipcFd;
|
||||
|
@ -274,17 +276,20 @@ public class GeckoThread extends Thread {
|
|||
|
||||
// argv[0] is the program name, which for us is the package name.
|
||||
args.add(context.getPackageName());
|
||||
args.add("-greomni");
|
||||
args.add(context.getPackageResourcePath());
|
||||
|
||||
final GeckoProfile profile = getProfile();
|
||||
if (profile.isCustomProfile()) {
|
||||
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 (!mInitInfo.xpcshell) {
|
||||
args.add("-greomni");
|
||||
args.add(context.getPackageResourcePath());
|
||||
|
||||
final GeckoProfile profile = getProfile();
|
||||
if (profile.isCustomProfile()) {
|
||||
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 (mInitInfo.args != null) {
|
||||
|
@ -435,7 +440,8 @@ public class GeckoThread extends Thread {
|
|||
final boolean isChildProcess = isChildProcess();
|
||||
|
||||
GeckoLoader.setupGeckoEnvironment(context, isChildProcess,
|
||||
context.getFilesDir().getPath(), env, mInitInfo.prefs);
|
||||
context.getFilesDir().getPath(), env, mInitInfo.prefs,
|
||||
mInitInfo.xpcshell);
|
||||
|
||||
initGeckoEnvironment();
|
||||
|
||||
|
@ -465,7 +471,9 @@ public class GeckoThread extends Thread {
|
|||
mInitInfo.extras.getInt(EXTRA_PREF_MAP_FD, -1),
|
||||
mInitInfo.extras.getInt(EXTRA_IPC_FD, -1),
|
||||
mInitInfo.extras.getInt(EXTRA_CRASH_FD, -1),
|
||||
mInitInfo.extras.getInt(EXTRA_CRASH_ANNOTATION_FD, -1));
|
||||
mInitInfo.extras.getInt(EXTRA_CRASH_ANNOTATION_FD, -1),
|
||||
isChildProcess ? false : mInitInfo.xpcshell,
|
||||
isChildProcess ? null : mInitInfo.outFilePath);
|
||||
|
||||
// And... we're done.
|
||||
final boolean restarting = isState(State.RESTARTING);
|
||||
|
|
|
@ -118,7 +118,8 @@ public final class GeckoLoader {
|
|||
final boolean isChildProcess,
|
||||
final String profilePath,
|
||||
final Collection<String> env,
|
||||
final Map<String, Object> prefs) {
|
||||
final Map<String, Object> prefs,
|
||||
final boolean xpcshell) {
|
||||
for (final String e : env) {
|
||||
putenv(e);
|
||||
}
|
||||
|
@ -156,12 +157,15 @@ public final class GeckoLoader {
|
|||
setupInitialPrefs(prefs);
|
||||
}
|
||||
|
||||
// setup the tmp path
|
||||
final File f = getTmpDir(context);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
// Xpcshell tests set up their own temp directory
|
||||
if (!xpcshell) {
|
||||
// setup the tmp path
|
||||
final File f = getTmpDir(context);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
putenv("TMPDIR=" + f.getPath());
|
||||
}
|
||||
putenv("TMPDIR=" + f.getPath());
|
||||
|
||||
putenv("LANG=" + Locale.getDefault().toString());
|
||||
|
||||
|
@ -496,7 +500,7 @@ public final class GeckoLoader {
|
|||
private static native void putenv(String map);
|
||||
|
||||
// These methods are implemented in mozglue/android/APKOpen.cpp
|
||||
public static native void nativeRun(String[] args, int prefsFd, int prefMapFd, int ipcFd, int crashFd, int crashAnnotationFd);
|
||||
public static native void nativeRun(String[] args, int prefsFd, int prefMapFd, int ipcFd, int crashFd, int crashAnnotationFd, boolean xpcshell, String outFilePath);
|
||||
private static native void loadGeckoLibsNative();
|
||||
private static native void loadSQLiteLibsNative();
|
||||
private static native void loadNSSLibsNative();
|
||||
|
|
|
@ -49,6 +49,7 @@ import org.mozilla.gecko.util.ThreadUtils;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -289,6 +290,27 @@ public final class GeckoRuntime implements Parcelable {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void setArguments(final Context context, final GeckoThread.InitInfo initInfo,
|
||||
final String[] arguments) {
|
||||
final List<String> result = new ArrayList<>(arguments.length);
|
||||
for (final String argument : arguments) {
|
||||
if ("-xpcshell".equals(argument)) {
|
||||
// Only debug builds of the test app can run an xpcshell
|
||||
if (!BuildConfig.DEBUG
|
||||
|| !"org.mozilla.geckoview.test".equals(
|
||||
context.getApplicationContext().getPackageName())) {
|
||||
throw new IllegalArgumentException("Only the test app can run -xpcshell.");
|
||||
}
|
||||
|
||||
initInfo.xpcshell = true;
|
||||
} else {
|
||||
result.add(argument);
|
||||
}
|
||||
}
|
||||
|
||||
initInfo.args = result.toArray(new String[]{});
|
||||
}
|
||||
|
||||
/* package */ boolean init(final @NonNull Context context, final @NonNull GeckoRuntimeSettings settings) {
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "init");
|
||||
|
@ -329,7 +351,10 @@ public final class GeckoRuntime implements Parcelable {
|
|||
GeckoFontScaleListener.getInstance().attachToContext(context, settings);
|
||||
|
||||
final GeckoThread.InitInfo info = new GeckoThread.InitInfo();
|
||||
info.args = settings.getArguments();
|
||||
setArguments(context, info, settings.getArguments());
|
||||
if (info.xpcshell) {
|
||||
info.outFilePath = settings.getExtras().getString("out_file");
|
||||
}
|
||||
info.extras = settings.getExtras();
|
||||
info.flags = flags;
|
||||
|
||||
|
|
|
@ -362,11 +362,10 @@ static void FreeArgv(char** argv, int argc) {
|
|||
}
|
||||
|
||||
extern "C" APKOPEN_EXPORT void MOZ_JNICALL
|
||||
Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(JNIEnv* jenv, jclass jc,
|
||||
jobjectArray jargs,
|
||||
int prefsFd, int prefMapFd,
|
||||
int ipcFd, int crashFd,
|
||||
int crashAnnotationFd) {
|
||||
Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(
|
||||
JNIEnv* jenv, jclass jc, jobjectArray jargs, int prefsFd, int prefMapFd,
|
||||
int ipcFd, int crashFd, int crashAnnotationFd, bool xpcshell,
|
||||
jstring outFilePath) {
|
||||
EnsureBaseProfilerInitialized();
|
||||
|
||||
int argc = 0;
|
||||
|
@ -381,7 +380,15 @@ Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(JNIEnv* jenv, jclass jc,
|
|||
#ifdef MOZ_LINKER
|
||||
ElfLoader::Singleton.ExpectShutdown(false);
|
||||
#endif
|
||||
gBootstrap->GeckoStart(jenv, argv, argc, sAppData);
|
||||
const char* outFilePathRaw = nullptr;
|
||||
if (xpcshell) {
|
||||
MOZ_ASSERT(outFilePath);
|
||||
outFilePathRaw = jenv->GetStringUTFChars(outFilePath, nullptr);
|
||||
}
|
||||
gBootstrap->GeckoStart(jenv, argv, argc, sAppData, xpcshell, outFilePathRaw);
|
||||
if (outFilePathRaw) {
|
||||
jenv->ReleaseStringUTFChars(outFilePath, outFilePathRaw);
|
||||
}
|
||||
#ifdef MOZ_LINKER
|
||||
ElfLoader::Singleton.ExpectShutdown(true);
|
||||
#endif
|
||||
|
|
|
@ -73,8 +73,9 @@ class BootstrapImpl final : public Bootstrap {
|
|||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
virtual void GeckoStart(JNIEnv* aEnv, char** argv, int argc,
|
||||
const StaticXREAppData& aAppData) override {
|
||||
::GeckoStart(aEnv, argv, argc, aAppData);
|
||||
const StaticXREAppData& aAppData,
|
||||
bool xpcshell, const char* outFilePath) override {
|
||||
::GeckoStart(aEnv, argv, argc, aAppData, xpcshell, outFilePath);
|
||||
}
|
||||
|
||||
virtual void XRE_SetAndroidChildFds(
|
||||
|
|
|
@ -28,7 +28,8 @@ struct StaticXREAppData;
|
|||
}
|
||||
|
||||
extern "C" NS_EXPORT void GeckoStart(JNIEnv* aEnv, char** argv, int argc,
|
||||
const mozilla::StaticXREAppData& aAppData);
|
||||
const mozilla::StaticXREAppData& aAppData,
|
||||
bool xpcshell, const char* outFilePath);
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
|
@ -120,7 +121,8 @@ class Bootstrap {
|
|||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
virtual void GeckoStart(JNIEnv* aEnv, char** argv, int argc,
|
||||
const StaticXREAppData& aAppData) = 0;
|
||||
const StaticXREAppData& aAppData, bool xpcshell,
|
||||
const char* outFilePath) = 0;
|
||||
|
||||
virtual void XRE_SetAndroidChildFds(JNIEnv* aEnv,
|
||||
const XRE_AndroidChildFds& fds) = 0;
|
||||
|
|
|
@ -17,13 +17,15 @@
|
|||
#include "nsAppRunner.h"
|
||||
#include "nsExceptionHandler.h"
|
||||
#include "mozilla/Bootstrap.h"
|
||||
#include "XREShellData.h"
|
||||
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, MOZ_APP_NAME, args)
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
extern "C" NS_EXPORT void GeckoStart(JNIEnv* env, char** argv, int argc,
|
||||
const StaticXREAppData& aAppData) {
|
||||
const StaticXREAppData& aAppData,
|
||||
bool xpcshell, const char* outFilePath) {
|
||||
mozilla::jni::SetGeckoThreadEnv(env);
|
||||
|
||||
if (!argv) {
|
||||
|
@ -31,11 +33,26 @@ extern "C" NS_EXPORT void GeckoStart(JNIEnv* env, char** argv, int argc,
|
|||
return;
|
||||
}
|
||||
|
||||
BootstrapConfig config;
|
||||
config.appData = &aAppData;
|
||||
config.appDataPath = nullptr;
|
||||
if (xpcshell) {
|
||||
XREShellData shellData;
|
||||
FILE* outFile = fopen(outFilePath, "w");
|
||||
if (!outFile) {
|
||||
LOG("XRE_XPCShellMain cannot open %s", outFilePath);
|
||||
return;
|
||||
}
|
||||
// We redirect both stdout and stderr to the same file, to conform with
|
||||
// what runxpcshell.py does on Desktop.
|
||||
shellData.outFile = outFile;
|
||||
shellData.errFile = outFile;
|
||||
int result = XRE_XPCShellMain(argc, argv, nullptr, &shellData);
|
||||
fclose(shellData.outFile);
|
||||
if (result) LOG("XRE_XPCShellMain returned %d", result);
|
||||
} else {
|
||||
BootstrapConfig config;
|
||||
config.appData = &aAppData;
|
||||
config.appDataPath = nullptr;
|
||||
|
||||
int result = XRE_main(argc, argv, config);
|
||||
|
||||
if (result) LOG("XRE_main returned %d", result);
|
||||
int result = XRE_main(argc, argv, config);
|
||||
if (result) LOG("XRE_main returned %d", result);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче