| Index: content/browser/child_process_launcher.cc
|
| diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc
|
| index cb2fa2d454dbc945f8789c5d1b6d8d8173dceb5b..257f71ac47a2acebc6abdeba2f7a2b7e14e07d33 100644
|
| --- a/content/browser/child_process_launcher.cc
|
| +++ b/content/browser/child_process_launcher.cc
|
| @@ -24,9 +24,13 @@
|
| #include "content/public/common/content_switches.h"
|
| #include "content/public/common/result_codes.h"
|
| #include "content/public/common/sandboxed_process_launcher_delegate.h"
|
| +#include "mojo/edk/embedder/embedder.h"
|
| +#include "mojo/edk/embedder/scoped_platform_handle.h"
|
|
|
| #if defined(OS_WIN)
|
| #include "base/files/file_path.h"
|
| +#include "base/win/scoped_handle.h"
|
| +#include "base/win/win_util.h"
|
| #include "content/common/sandbox_win.h"
|
| #include "content/public/common/sandbox_init.h"
|
| #elif defined(OS_MACOSX)
|
| @@ -59,6 +63,7 @@ namespace {
|
| typedef base::Callback<void(ZygoteHandle,
|
| #if defined(OS_ANDROID)
|
| base::ScopedFD,
|
| + base::ScopedFD,
|
| #endif
|
| base::Process)> NotifyCallback;
|
|
|
| @@ -82,6 +87,7 @@ void OnChildProcessStartedAndroid(const NotifyCallback& callback,
|
| BrowserThread::ID client_thread_id,
|
| const base::TimeTicks begin_launch_time,
|
| base::ScopedFD ipcfd,
|
| + base::ScopedFD mojo_fd,
|
| base::ProcessHandle handle) {
|
| // This can be called on the launcher thread or UI thread.
|
| base::TimeDelta launch_time = base::TimeTicks::Now() - begin_launch_time;
|
| @@ -91,7 +97,7 @@ void OnChildProcessStartedAndroid(const NotifyCallback& callback,
|
|
|
| base::Closure callback_on_client_thread(
|
| base::Bind(callback, nullptr, base::Passed(&ipcfd),
|
| - base::Passed(base::Process(handle))));
|
| + base::Passed(&mojo_fd), base::Passed(base::Process(handle))));
|
| if (BrowserThread::CurrentlyOn(client_thread_id)) {
|
| callback_on_client_thread.Run();
|
| } else {
|
| @@ -108,6 +114,7 @@ void LaunchOnLauncherThread(const NotifyCallback& callback,
|
| #if defined(OS_ANDROID)
|
| base::ScopedFD ipcfd,
|
| #endif
|
| + mojo::edk::ScopedPlatformHandle client_handle,
|
| base::CommandLine* cmd_line) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
|
| scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate);
|
| @@ -129,12 +136,19 @@ void LaunchOnLauncherThread(const NotifyCallback& callback,
|
| base::Process process;
|
| #if defined(OS_WIN)
|
| if (launch_elevated) {
|
| + // TODO(rockot): We may want to support Mojo IPC to elevated processes as
|
| + // well, but this isn't currently feasible without sharing a pipe path on
|
| + // the command line as elevated process launch goes through ShellExecuteEx.
|
| base::LaunchOptions options;
|
| options.start_hidden = true;
|
| process = base::LaunchElevatedProcess(*cmd_line, options);
|
| } else {
|
| - process = StartSandboxedProcess(
|
| - delegate, cmd_line, base::HandlesToInheritVector());
|
| + base::HandlesToInheritVector handles;
|
| + handles.push_back(client_handle.get().handle);
|
| + cmd_line->AppendSwitchASCII(
|
| + mojo::edk::PlatformChannelPair::kMojoPlatformChannelHandleSwitch,
|
| + base::UintToString(base::win::HandleToUint32(handles[0])));
|
| + process = StartSandboxedProcess(delegate, cmd_line, handles);
|
| }
|
| #elif defined(OS_POSIX)
|
| std::string process_type =
|
| @@ -142,10 +156,15 @@ void LaunchOnLauncherThread(const NotifyCallback& callback,
|
| scoped_ptr<FileDescriptorInfo> files_to_register(
|
| FileDescriptorInfoImpl::Create());
|
|
|
| + base::ScopedFD mojo_fd(client_handle.release().handle);
|
| + DCHECK(mojo_fd.is_valid());
|
| +
|
| #if defined(OS_ANDROID)
|
| files_to_register->Share(kPrimaryIPCChannel, ipcfd.get());
|
| + files_to_register->Share(kMojoIPCChannel, mojo_fd.get());
|
| #else
|
| files_to_register->Transfer(kPrimaryIPCChannel, std::move(ipcfd));
|
| + files_to_register->Transfer(kMojoIPCChannel, std::move(mojo_fd));
|
| #endif
|
| #endif
|
|
|
| @@ -223,7 +242,8 @@ void LaunchOnLauncherThread(const NotifyCallback& callback,
|
| StartChildProcess(
|
| cmd_line->argv(), child_process_id, std::move(files_to_register), regions,
|
| base::Bind(&OnChildProcessStartedAndroid, callback, client_thread_id,
|
| - begin_launch_time, base::Passed(&ipcfd)));
|
| + begin_launch_time, base::Passed(&ipcfd),
|
| + base::Passed(&mojo_fd)));
|
|
|
| #elif defined(OS_POSIX)
|
| // We need to close the client end of the IPC channel to reliably detect
|
| @@ -423,6 +443,8 @@ void ChildProcessLauncher::Launch(
|
| NotifyCallback reply_callback(base::Bind(&ChildProcessLauncher::DidLaunch,
|
| weak_factory_.GetWeakPtr(),
|
| terminate_child_on_shutdown_));
|
| + mojo::edk::ScopedPlatformHandle client_handle =
|
| + mojo_platform_channel_.PassClientHandle();
|
| BrowserThread::PostTask(
|
| BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
|
| base::Bind(&LaunchOnLauncherThread, reply_callback, client_thread_id_,
|
| @@ -430,7 +452,7 @@ void ChildProcessLauncher::Launch(
|
| #if defined(OS_ANDROID)
|
| base::Passed(&ipcfd),
|
| #endif
|
| - cmd_line));
|
| + base::Passed(&client_handle), cmd_line));
|
| }
|
|
|
| void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) {
|
| @@ -474,6 +496,7 @@ void ChildProcessLauncher::DidLaunch(
|
| ZygoteHandle zygote,
|
| #if defined(OS_ANDROID)
|
| base::ScopedFD ipcfd,
|
| + base::ScopedFD mojo_fd,
|
| #endif
|
| base::Process process) {
|
| if (!process.IsValid())
|
| @@ -505,6 +528,12 @@ void ChildProcessLauncher::Notify(ZygoteHandle zygote,
|
| starting_ = false;
|
| process_ = std::move(process);
|
|
|
| + if (process_.IsValid()) {
|
| + // Set up Mojo IPC to the new process.
|
| + mojo::edk::ChildProcessLaunched(process_.Handle(),
|
| + mojo_platform_channel_.PassServerHandle());
|
| + }
|
| +
|
| #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
|
| zygote_ = zygote;
|
| #endif
|
|
|