--- a/dom/ipc/ContentProcess.cpp
+++ b/dom/ipc/ContentProcess.cpp
@@ -78,22 +78,29 @@ SetUpSandboxEnvironment()
}
SetTmpEnvironmentVariable(sandboxedContentTemp);
}
#endif
#ifdef ANDROID
static int gPrefsFd = -1;
+static int gPrefMapFd = -1;
void
SetPrefsFd(int aFd)
{
gPrefsFd = aFd;
}
+
+void
+SetPrefMapFd(int aFd)
+{
+ gPrefMapFd = aFd;
+}
#endif
bool
ContentProcess::Init(int aArgc, char* aArgv[])
{
Maybe<uint64_t> childID;
Maybe<bool> isForBrowser;
Maybe<base::SharedMemoryHandle> prefsHandle;
@@ -223,16 +230,19 @@ ContentProcess::Init(int aArgc, char* aA
#endif /* XP_MACOSX && MOZ_CONTENT_SANDBOX */
}
}
#ifdef ANDROID
// Android is different; get the FD via gPrefsFd instead of a fixed fd.
MOZ_RELEASE_ASSERT(gPrefsFd != -1);
prefsHandle = Some(base::FileDescriptor(gPrefsFd, /* auto_close */ true));
+
+ FileDescriptor::UniquePlatformHandle handle(gPrefMapFd);
+ prefMapHandle.emplace(handle.get());
#elif XP_UNIX
prefsHandle = Some(base::FileDescriptor(kPrefsFileDescriptor,
/* auto_close */ true));
// The FileDescriptor constructor will clone this handle when constructed,
// so store it in a UniquePlatformHandle to make sure the original gets
// closed.
FileDescriptor::UniquePlatformHandle handle(kPrefMapFileDescriptor);
--- a/dom/ipc/ContentProcess.h
+++ b/dom/ipc/ContentProcess.h
@@ -45,16 +45,17 @@ private:
// This object initializes and configures COM.
mozilla::mscom::MainThreadRuntime mCOMRuntime;
#endif
DISALLOW_EVIL_CONSTRUCTORS(ContentProcess);
};
#ifdef ANDROID
-// Android doesn't use -prefsHandle, it gets that FD another way.
+// Android doesn't use -prefsHandle, it gets that FDs another way.
void SetPrefsFd(int aFd);
+void SetPrefMapFd(int aFd);
#endif
} // namespace dom
} // namespace mozilla
#endif // ifndef dom_tabs_ContentThread_h
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -1253,26 +1253,27 @@ GeckoChildProcessHost::LaunchAndroidServ
}
// XXX: this processing depends entirely on the internals of
// ContentParent::LaunchSubprocess()
// GeckoChildProcessHost::PerformAsyncLaunchInternal(), and the order in
// which they append to fds_to_remap. There must be a better way to do it.
// See bug 1440207.
int32_t prefsFd = fds_to_remap[0].first;
- int32_t ipcFd = fds_to_remap[1].first;
+ int32_t prefMapFd = fds_to_remap[1].first;
+ int32_t ipcFd = fds_to_remap[2].first;
int32_t crashFd = -1;
int32_t crashAnnotationFd = -1;
- if (fds_to_remap.size() == 3) {
- crashAnnotationFd = fds_to_remap[2].first;
- }
if (fds_to_remap.size() == 4) {
- crashFd = fds_to_remap[2].first;
crashAnnotationFd = fds_to_remap[3].first;
}
+ if (fds_to_remap.size() == 5) {
+ crashFd = fds_to_remap[3].first;
+ crashAnnotationFd = fds_to_remap[4].first;
+ }
- int32_t handle = java::GeckoProcessManager::Start(type, jargs, prefsFd, ipcFd, crashFd, crashAnnotationFd);
+ int32_t handle = java::GeckoProcessManager::Start(type, jargs, prefsFd, prefMapFd, ipcFd, crashFd, crashAnnotationFd);
if (process_handle) {
*process_handle = handle;
}
}
#endif
--- 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
@@ -7,14 +7,15 @@ 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, int flags,
- in ParcelFileDescriptor prefsPfd, in ParcelFileDescriptor ipcPfd,
+ in ParcelFileDescriptor prefsPfd, in ParcelFileDescriptor prefMapPfd,
+ in ParcelFileDescriptor ipcPfd,
in ParcelFileDescriptor crashReporterPfd,
in ParcelFileDescriptor crashAnnotationPfd);
void crash();
}
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java
@@ -127,16 +127,17 @@ public class GeckoThread extends Thread
// Main process parameters
public static final int FLAG_DEBUGGING = 1 << 0; // Debugging mode.
public static final int FLAG_PRELOAD_CHILD = 1 << 1; // Preload child during main thread start.
public static final int FLAG_ENABLE_NATIVE_CRASHREPORTER = 1 << 2; // Enable native crash reporting
public static final int FLAG_ENABLE_JAVA_CRASHREPORTER = 1 << 3; // Enable java crash reporting
/* package */ static final String EXTRA_ARGS = "args";
private static final String EXTRA_PREFS_FD = "prefsFd";
+ private static final String EXTRA_PREF_MAP_FD = "prefMapFd";
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 boolean mInitialized;
private GeckoProfile mProfile;
private String[] mArgs;
private Bundle mExtras;
@@ -148,56 +149,60 @@ public class GeckoThread extends Thread
@WrapForJNI
private static boolean isChildProcess() {
return INSTANCE.mExtras.getInt(EXTRA_IPC_FD, -1) != -1;
}
private synchronized boolean init(final GeckoProfile profile, final String[] args,
final Bundle extras, final int flags,
- final int prefsFd, final int ipcFd,
+ final int prefsFd, final int prefMapFd,
+ final int ipcFd,
final int crashFd,
final int crashAnnotationFd) {
ThreadUtils.assertOnUiThread();
uiThreadId = android.os.Process.myTid();
if (mInitialized) {
return false;
}
mProfile = profile;
mArgs = args;
mFlags = flags;
mExtras = (extras != null) ? new Bundle(extras) : new Bundle(3);
mExtras.putInt(EXTRA_PREFS_FD, prefsFd);
+ mExtras.putInt(EXTRA_PREF_MAP_FD, prefMapFd);
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[] args,
final Bundle extras, final int flags) {
return INSTANCE.init(profile, args, extras, flags, /* fd */ -1,
- /* fd */ -1, /* fd */ -1, /* fd */ -1);
+ /* fd */ -1, /* fd */ -1, /* fd */ -1,
+ /* fd */ -1);
}
public static boolean initChildProcess(final String[] args,
final Bundle extras,
final int flags,
final int prefsFd,
+ final int prefMapFd,
final int ipcFd,
final int crashFd,
final int crashAnnotationFd) {
return INSTANCE.init(/* profile */ null, args, extras, flags,
- prefsFd, ipcFd, crashFd, crashAnnotationFd);
+ prefsFd, prefMapFd, 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;
}
@@ -492,16 +497,17 @@ public class GeckoThread extends Thread
GeckoAppShell.ensureCrashHandling();
}
GeckoLoader.setupGeckoEnvironment(context, context.getFilesDir().getPath(), env);
// And go.
GeckoLoader.nativeRun(args,
mExtras.getInt(EXTRA_PREFS_FD, -1),
+ mExtras.getInt(EXTRA_PREF_MAP_FD, -1),
mExtras.getInt(EXTRA_IPC_FD, -1),
mExtras.getInt(EXTRA_CRASH_FD, -1),
mExtras.getInt(EXTRA_CRASH_ANNOTATION_FD, -1));
// And... we're done.
final boolean restarting = isState(State.RESTARTING);
setState(State.EXITED);
--- 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
@@ -451,15 +451,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 prefsFd, int ipcFd, int crashFd, int crashAnnotationFd);
+ public static native void nativeRun(String[] args, int prefsFd, int prefMapFd, int ipcFd, int crashFd, 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/process/GeckoProcessManager.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/process/GeckoProcessManager.java
@@ -177,67 +177,71 @@ public final class GeckoProcessManager e
try {
mConnections.get("tab").bind().crash();
} catch (RemoteException e) {
}
}
@WrapForJNI
private static int start(final String type, final String[] args,
- final int prefsFd, final int ipcFd,
+ final int prefsFd, final int prefMapFd,
+ final int ipcFd,
final int crashFd, final int crashAnnotationFd) {
- return INSTANCE.start(type, args, prefsFd, ipcFd, crashFd, crashAnnotationFd, /* retry */ false);
+ return INSTANCE.start(type, args, prefsFd, prefMapFd, ipcFd, crashFd, crashAnnotationFd, /* retry */ false);
}
private int filterFlagsForChild(int flags) {
return flags & (GeckoThread.FLAG_ENABLE_JAVA_CRASHREPORTER |
GeckoThread.FLAG_ENABLE_NATIVE_CRASHREPORTER);
}
- private int start(final String type, final String[] args, final int prefsFd,
+ private int start(final String type, final String[] args,
+ final int prefsFd, final int prefMapFd,
final int ipcFd, final int crashFd,
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 prefsPfd;
+ final ParcelFileDescriptor prefMapPfd;
final ParcelFileDescriptor ipcPfd;
final ParcelFileDescriptor crashPfd;
final ParcelFileDescriptor crashAnnotationPfd;
try {
prefsPfd = ParcelFileDescriptor.fromFd(prefsFd);
+ prefMapPfd = ParcelFileDescriptor.fromFd(prefMapFd);
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;
}
final int flags = filterFlagsForChild(GeckoThread.getActiveFlags());
boolean started = false;
try {
- started = child.start(this, args, extras, flags, prefsPfd, ipcPfd, crashPfd,
- crashAnnotationPfd);
+ started = child.start(this, args, extras, flags, prefsPfd, prefMapPfd,
+ ipcPfd, crashPfd, 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, prefsFd, ipcFd, crashFd, crashAnnotationFd, /* retry */ true);
+ return start(type, args, prefsFd, prefMapFd, ipcFd, crashFd, crashAnnotationFd, /* retry */ true);
}
try {
if (crashAnnotationPfd != null) {
crashAnnotationPfd.close();
}
if (crashPfd != null) {
crashPfd.close();
--- 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
@@ -57,39 +57,41 @@ public class GeckoServiceChildProcess ex
}
@Override
public boolean start(final IProcessManager procMan,
final String[] args,
final Bundle extras,
final int flags,
final ParcelFileDescriptor prefsPfd,
+ final ParcelFileDescriptor prefMapPfd,
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 prefsFd = prefsPfd.detachFd();
+ final int prefMapFd = prefMapPfd.detachFd();
final int ipcFd = ipcPfd.detachFd();
final int crashReporterFd = crashReporterPfd != null ?
crashReporterPfd.detachFd() : -1;
final int crashAnnotationFd = crashAnnotationPfd != null ?
crashAnnotationPfd.detachFd() : -1;
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
- if (GeckoThread.initChildProcess(args, extras, flags, prefsFd, ipcFd, crashReporterFd,
- crashAnnotationFd)) {
+ if (GeckoThread.initChildProcess(args, extras, flags, prefsFd, prefMapFd, ipcFd,
+ crashReporterFd, crashAnnotationFd)) {
GeckoThread.launch();
}
}
});
return true;
}
@Override
--- a/mozglue/android/APKOpen.cpp
+++ b/mozglue/android/APKOpen.cpp
@@ -388,32 +388,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 prefsFd, 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)
{
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, { prefsFd, ipcFd, crashFd, crashAnnotationFd });
+ gBootstrap->XRE_SetAndroidChildFds(jenv, { prefsFd, prefMapFd, ipcFd, crashFd, crashAnnotationFd });
gBootstrap->XRE_SetProcessType(argv[argc - 1]);
XREChildData childData;
gBootstrap->XRE_InitChildProcess(argc - 1, argv, &childData);
}
gBootstrap.reset();
FreeArgv(argv, argc);
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -243,16 +243,17 @@ GeckoProcessType sChildProcessType = Gec
} // namespace mozilla
#if defined(MOZ_WIDGET_ANDROID)
void
XRE_SetAndroidChildFds (JNIEnv* env, const XRE_AndroidChildFds& fds)
{
mozilla::jni::SetGeckoThreadEnv(env);
mozilla::dom::SetPrefsFd(fds.mPrefsFd);
+ mozilla::dom::SetPrefMapFd(fds.mPrefMapFd);
IPC::Channel::SetClientChannelFd(fds.mIpcFd);
CrashReporter::SetNotificationPipeForChild(fds.mCrashFd);
CrashReporter::SetCrashAnnotationPipeForChild(fds.mCrashAnnotationFd);
}
#endif // defined(MOZ_WIDGET_ANDROID)
void
XRE_SetProcessType(const char* aProcessTypeString)
--- a/xpcom/build/nsXULAppAPI.h
+++ b/xpcom/build/nsXULAppAPI.h
@@ -395,16 +395,17 @@ static_assert(MOZ_ARRAY_LENGTH(kGeckoPro
XRE_API(const char*,
XRE_ChildProcessTypeToString, (GeckoProcessType aProcessType))
#if defined(MOZ_WIDGET_ANDROID)
struct XRE_AndroidChildFds
{
int mPrefsFd;
+ int mPrefMapFd;
int mIpcFd;
int mCrashFd;
int mCrashAnnotationFd;
};
XRE_API(void,
XRE_SetAndroidChildFds, (JNIEnv* env, const XRE_AndroidChildFds& fds))
#endif // defined(MOZ_WIDGET_ANDROID)