| Index: content/browser/child_process_launcher.cc
|
| diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc
|
| index e92554c8aa5a423b6b6f91d2f2e77b67cb414c03..bb31e81c3a8c5e9dfca60e8128a86ff70f5cfc0b 100644
|
| --- a/content/browser/child_process_launcher.cc
|
| +++ b/content/browser/child_process_launcher.cc
|
| @@ -14,7 +14,10 @@
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/metrics/histogram.h"
|
| #include "base/process/process.h"
|
| +#include "base/rand_util.h"
|
| #include "base/strings/string_number_conversions.h"
|
| +#include "base/strings/stringprintf.h"
|
| +#include "base/strings/utf_string_conversions.h"
|
| #include "base/synchronization/lock.h"
|
| #include "base/threading/thread.h"
|
| #include "build/build_config.h"
|
| @@ -23,6 +26,9 @@
|
| #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/platform_channel_pair.h"
|
| +#include "mojo/edk/embedder/scoped_platform_handle.h"
|
|
|
| #if defined(OS_WIN)
|
| #include "base/files/file_path.h"
|
| @@ -58,6 +64,7 @@ namespace {
|
| typedef base::Callback<void(ZygoteHandle,
|
| #if defined(OS_ANDROID)
|
| base::ScopedFD,
|
| + base::ScopedFD,
|
| #endif
|
| base::Process)> NotifyCallback;
|
|
|
| @@ -74,6 +81,38 @@ void RecordHistogramsOnLauncherThread(base::TimeDelta launch_time) {
|
| }
|
| }
|
|
|
| +#if defined(OS_WIN)
|
| +// This generates a pipe name and secret to use for the Mojo IPC channel on
|
| +// Windows.
|
| +mojo::edk::ScopedPlatformHandle CreateMojoNamedPipe(base::CommandLine* cmd_line,
|
| + std::string* secret) {
|
| + std::string pipe_name =
|
| + base::StringPrintf("\\\\.\\pipe\\chrome.%u.%u.%I64u",
|
| + GetCurrentProcessId(), GetCurrentThreadId(),
|
| + base::RandUint64());
|
| + std::string pipe_secret = mojo::edk::GenerateRandomToken();
|
| +
|
| + const DWORD kOpenMode = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
|
| + FILE_FLAG_FIRST_PIPE_INSTANCE;
|
| + const DWORD kPipeMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE;
|
| + mojo::edk::ScopedPlatformHandle pipe(mojo::edk::PlatformHandle(
|
| + CreateNamedPipeW(base::UTF8ToWide(pipe_name).c_str(), kOpenMode,
|
| + kPipeMode,
|
| + 1, // Max instances.
|
| + 4096, // Out buffer size.
|
| + 4096, // In buffer size.
|
| + 5000, // Timeout in milliseconds.
|
| + nullptr))); // Default security descriptor.
|
| + PCHECK(pipe.is_valid());
|
| +
|
| + cmd_line->AppendSwitchASCII(switches::kMojoChannelName, pipe_name);
|
| + cmd_line->AppendSwitchASCII(switches::kMojoChannelSecret, pipe_secret);
|
| +
|
| + *secret = pipe_secret;
|
| + return pipe;
|
| +}
|
| +#endif
|
| +
|
| #if defined(OS_ANDROID)
|
| // TODO(sievers): Remove this by defining better what happens on what
|
| // thread in the corresponding Java code.
|
| @@ -81,6 +120,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;
|
| @@ -90,7 +130,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 {
|
| @@ -107,6 +147,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);
|
| @@ -140,10 +181,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
|
|
|
| @@ -221,7 +267,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
|
| @@ -421,6 +468,14 @@ void ChildProcessLauncher::Launch(
|
| NotifyCallback reply_callback(base::Bind(&ChildProcessLauncher::DidLaunch,
|
| weak_factory_.GetWeakPtr(),
|
| terminate_child_on_shutdown_));
|
| + mojo::edk::ScopedPlatformHandle client_handle;
|
| +#if defined(OS_WIN)
|
| + mojo_server_handle_ = CreateMojoNamedPipe(cmd_line, &mojo_secret_);
|
| +#else
|
| + mojo::edk::PlatformChannelPair platform_channel;
|
| + client_handle = platform_channel.PassClientHandle();
|
| + mojo_server_handle_ = platform_channel.PassServerHandle();
|
| +#endif
|
| BrowserThread::PostTask(
|
| BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
|
| base::Bind(&LaunchOnLauncherThread, reply_callback, client_thread_id_,
|
| @@ -428,7 +483,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) {
|
| @@ -472,6 +527,7 @@ void ChildProcessLauncher::DidLaunch(
|
| ZygoteHandle zygote,
|
| #if defined(OS_ANDROID)
|
| base::ScopedFD ipcfd,
|
| + base::ScopedFD mojo_fd,
|
| #endif
|
| base::Process process) {
|
| if (!process.IsValid())
|
| @@ -503,6 +559,18 @@ void ChildProcessLauncher::Notify(ZygoteHandle zygote,
|
| starting_ = false;
|
| process_ = std::move(process);
|
|
|
| + if (process_.IsValid()) {
|
| + // Set up Mojo IPC to the new process.
|
| +#if defined(OS_WIN)
|
| + mojo::edk::ChildProcessLaunched(process_.Handle(),
|
| + std::move(mojo_server_handle_),
|
| + mojo_secret_);
|
| +#else
|
| + mojo::edk::ChildProcessLaunched(process_.Handle(),
|
| + std::move(mojo_server_handle_));
|
| +#endif // defined(OS_WIN)
|
| + }
|
| +
|
| #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
|
| zygote_ = zygote;
|
| #endif
|
|
|