Bug 1314466 - part 4, update GeckoChildProcessHost to call LaunchAndroidService r=billm
authorRandall Barker <rbarker@mozilla.com>
Wed, 05 Oct 2016 16:37:35 -0700
changeset 322545 524f33fa66c6dc47c084c68aa777ff09ea0c804b
parent 322544 d6e36e11cfa3700f172c731fb5c899f64446cab4
child 322546 a8198e0db7b505acc7d83be4684d5b7fd06c53e4
push id30952
push usercbook@mozilla.com
push dateTue, 15 Nov 2016 11:27:04 +0000
treeherdermozilla-central@e16d1a881481 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1314466
milestone52.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 1314466 - part 4, update GeckoChildProcessHost to call LaunchAndroidService r=billm
ipc/glue/GeckoChildProcessHost.cpp
ipc/glue/GeckoChildProcessHost.h
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -55,25 +55,21 @@
 #include "nsClassHashtable.h"
 #include "nsHashKeys.h"
 #include "nsNativeCharsetUtils.h"
 #include "nscore.h" // for NS_FREE_PERMANENT_DATA
 
 using mozilla::MonitorAutoLock;
 using mozilla::ipc::GeckoChildProcessHost;
 
-#ifdef ANDROID
-// Like its predecessor in nsExceptionHandler.cpp, this is
-// the magic number of a file descriptor remapping we must
-// preserve for the child process.
-static const int kMagicAndroidSystemPropFd = 5;
-#endif
-
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
+#include "GeneratedJNIWrappers.h"
+#include "mozilla/jni/Refs.h"
+#include "mozilla/jni/Utils.h"
 #endif
 
 static const bool kLowRightsSubprocesses =
   // We currently only attempt to drop privileges on gonk, because we
   // have no plugins or extensions to worry about breaking.
 #ifdef MOZ_WIDGET_GONK
   true
 #else
@@ -186,27 +182,17 @@ GeckoChildProcessHost::GetPathToBinary(F
 #ifdef OS_WIN
     exePath = FilePath::FromWStringHack(CommandLine::ForCurrentProcess()->program());
 #else
     exePath = FilePath(CommandLine::ForCurrentProcess()->argv()[0]);
 #endif
     exePath = exePath.DirName();
   }
 
-#ifdef MOZ_WIDGET_ANDROID
-  exePath = exePath.AppendASCII("lib");
-
-  // We must use the PIE binary on 5.0 and higher
-  const char* processName = mozilla::AndroidBridge::Bridge()->GetAPIVersion() >= 21 ?
-    MOZ_CHILD_PROCESS_NAME_PIE : MOZ_CHILD_PROCESS_NAME;
-
-  exePath = exePath.AppendASCII(processName);
-#else
   exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_NAME);
-#endif
 
   return BinaryPathType::PluginContainer;
 }
 
 #ifdef MOZ_WIDGET_COCOA
 class AutoCFTypeObject {
 public:
   explicit AutoCFTypeObject(CFTypeRef object)
@@ -762,19 +748,16 @@ GeckoChildProcessHost::PerformAsyncLaunc
   // to initialize XPCOM just for the directory service, especially
   // since LD_LIBRARY_PATH is already set correctly in subprocesses
   // (meaning that we don't need to set that up in the environment).
   if (ShouldHaveDirectoryService()) {
     MOZ_ASSERT(gGREBinPath);
     nsCString path;
     NS_CopyUnicodeToNative(nsDependentString(gGREBinPath), path);
 # if defined(OS_LINUX) || defined(OS_BSD)
-#  if defined(MOZ_WIDGET_ANDROID)
-    path += "/lib";
-#  endif  // MOZ_WIDGET_ANDROID
     const char *ld_library_path = PR_GetEnv("LD_LIBRARY_PATH");
     nsCString new_ld_lib_path(path.get());
 
 #  if (MOZ_WIDGET_GTK == 3)
     if (mProcessType == GeckoProcessType_Plugin) {
       new_ld_lib_path.Append("/gtk2:");
       new_ld_lib_path.Append(path.get());
     }
@@ -808,38 +791,16 @@ GeckoChildProcessHost::PerformAsyncLaunc
     newEnvVars["DYLD_INSERT_LIBRARIES"] = interpose.get();
 # endif  // OS_LINUX
   }
 #endif  // OS_LINUX || OS_MACOSX
 
   FilePath exePath;
   BinaryPathType pathType = GetPathToBinary(exePath, mProcessType);
 
-#ifdef MOZ_WIDGET_ANDROID
-  // The java wrapper unpacks this for us but can't make it executable
-  chmod(exePath.value().c_str(), 0700);
-#endif  // MOZ_WIDGET_ANDROID
-
-#ifdef ANDROID
-  // Remap the Android property workspace to a well-known int,
-  // and update the environment to reflect the new value for the
-  // child process.
-  const char *apws = getenv("ANDROID_PROPERTY_WORKSPACE");
-  if (apws) {
-    int fd = atoi(apws);
-    mFileMap.push_back(std::pair<int, int>(fd, kMagicAndroidSystemPropFd));
-
-    char buf[32];
-    char *szptr = strchr(apws, ',');
-
-    snprintf(buf, sizeof(buf), "%d%s", kMagicAndroidSystemPropFd, szptr);
-    newEnvVars["ANDROID_PROPERTY_WORKSPACE"] = buf;
-  }
-#endif  // ANDROID
-
 #ifdef MOZ_WIDGET_GONK
   if (const char *ldPreloadPath = getenv("LD_PRELOAD")) {
     newEnvVars["LD_PRELOAD"] = ldPreloadPath;
   }
 #endif // MOZ_WIDGET_GONK
 
 #if defined(XP_LINUX) && defined(MOZ_SANDBOX)
   // Preload libmozsandbox.so so that sandbox-related interpositions
@@ -930,21 +891,25 @@ GeckoChildProcessHost::PerformAsyncLaunc
   // can't pretend being the child that's forked off.
   std::string mach_connection_name = StringPrintf("org.mozilla.machname.%d",
                                                   base::RandInt(0, std::numeric_limits<int>::max()));
   childArgv.push_back(mach_connection_name.c_str());
 #endif
 
   childArgv.push_back(childProcessType);
 
+#if defined(MOZ_WIDGET_ANDROID)
+  LaunchAndroidService(childProcessType, childArgv, mFileMap, &process);
+#else
   base::LaunchApp(childArgv, mFileMap,
 #if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD)
                   newEnvVars, privs,
 #endif
                   false, &process, arch);
+#endif // defined(MOZ_WIDGET_ANDROID)
 
   // We're in the parent and the child was launched. Close the child FD in the
   // parent as soon as possible, which will allow the parent to detect when the
   // child closes its FD (either due to normal exit or due to crash).
   GetChannel()->CloseClientFileDescriptor();
 
 #ifdef MOZ_WIDGET_COCOA
   // Wait for the child process to send us its 'task_t' data.
@@ -1261,8 +1226,37 @@ GeckoChildProcessHost::GetQueuedMessages
 {
   // If this is called off the IO thread, bad things will happen.
   DCHECK(MessageLoopForIO::current());
   swap(queue, mQueue);
   // We expect the next listener to take over processing of our queue.
 }
 
 bool GeckoChildProcessHost::sRunSelfAsContentProc(false);
+
+#ifdef MOZ_WIDGET_ANDROID
+void
+GeckoChildProcessHost::LaunchAndroidService(const char* type,
+                                            const std::vector<std::string>& argv,
+                                            const base::file_handle_mapping_vector& fds_to_remap,
+                                            ProcessHandle* process_handle)
+{
+  MOZ_ASSERT((fds_to_remap.size() > 0) && (fds_to_remap.size() <= 2));
+  JNIEnv* env = mozilla::jni::GetEnvForThread();
+  MOZ_ASSERT(env);
+
+  int argvSize = argv.size();
+  jni::ObjectArray::LocalRef jargs = jni::ObjectArray::LocalRef::Adopt(env->NewObjectArray(argvSize, env->FindClass("java/lang/String"), nullptr));
+  for (int ix = 0; ix < argvSize; ix++) {
+    jargs->SetElement(ix, jni::StringParam(argv[ix].c_str(), env));
+  }
+  base::file_handle_mapping_vector::const_iterator it = fds_to_remap.begin();
+  int32_t ipcFd = it->first;
+  it++;
+  // If the Crash Reporter is disabled, there will not be a second file descriptor.
+  int32_t crashFd = (it != fds_to_remap.end()) ? it->first : -1;
+  int32_t handle = java::GeckoAppShell::StartGeckoServiceChildProcess(type, jargs, crashFd, ipcFd);
+
+  if (process_handle) {
+    *process_handle = handle;
+  }
+}
+#endif
--- a/ipc/glue/GeckoChildProcessHost.h
+++ b/ipc/glue/GeckoChildProcessHost.h
@@ -210,14 +210,22 @@ private:
   // simple way how to change environment of a child process than to modify
   // the current environment).
   nsCString mRestoreOrigNSPRLogName;
   nsCString mRestoreOrigMozLogName;
 
   static uint32_t sNextUniqueID;
 
   static bool sRunSelfAsContentProc;
+
+#if defined(MOZ_WIDGET_ANDROID)
+  void LaunchAndroidService(const char* type,
+                            const std::vector<std::string>& argv,
+                            const base::file_handle_mapping_vector& fds_to_remap,
+                            ProcessHandle* process_handle);
+#endif // defined(MOZ_WIDGET_ANDROID)
+
 };
 
 } /* namespace ipc */
 } /* namespace mozilla */
 
 #endif /* __IPC_GLUE_GECKOCHILDPROCESSHOST_H__ */