summaryrefslogtreecommitdiffstats
path: root/chrome/browser/nacl_host
diff options
context:
space:
mode:
authorgregoryd@google.com <gregoryd@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-11 23:09:29 +0000
committergregoryd@google.com <gregoryd@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-11 23:09:29 +0000
commite15a4faf072c7627b2e4ce1801aaf7dafe035a5f (patch)
treeaad5fde8d7eb4e3afdabdf753161b665d166af8f /chrome/browser/nacl_host
parent21fb0112d27b4a26114d1b359de514d80376dbe1 (diff)
downloadchromium_src-e15a4faf072c7627b2e4ce1801aaf7dafe035a5f.zip
chromium_src-e15a4faf072c7627b2e4ce1801aaf7dafe035a5f.tar.gz
chromium_src-e15a4faf072c7627b2e4ce1801aaf7dafe035a5f.tar.bz2
Move nacl_process_host files into browser/nacl_host
Review URL: http://codereview.chromium.org/566023 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38849 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/nacl_host')
-rw-r--r--chrome/browser/nacl_host/nacl_broker_host.cc2
-rw-r--r--chrome/browser/nacl_host/nacl_broker_service.cc2
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.cc236
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.h82
4 files changed, 320 insertions, 2 deletions
diff --git a/chrome/browser/nacl_host/nacl_broker_host.cc b/chrome/browser/nacl_host/nacl_broker_host.cc
index 8abc228..92ed181 100644
--- a/chrome/browser/nacl_host/nacl_broker_host.cc
+++ b/chrome/browser/nacl_host/nacl_broker_host.cc
@@ -8,7 +8,7 @@
#include "ipc/ipc_switches.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/nacl_host/nacl_broker_service.h"
-#include "chrome/browser/nacl_process_host.h"
+#include "chrome/browser/nacl_host/nacl_process_host.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/nacl_cmd_line.h"
diff --git a/chrome/browser/nacl_host/nacl_broker_service.cc b/chrome/browser/nacl_host/nacl_broker_service.cc
index ef659cd..76da887 100644
--- a/chrome/browser/nacl_host/nacl_broker_service.cc
+++ b/chrome/browser/nacl_host/nacl_broker_service.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/nacl_host/nacl_broker_service.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/nacl_process_host.h"
+#include "chrome/browser/nacl_host/nacl_process_host.h"
#include "chrome/common/chrome_switches.h"
NaClBrokerService* NaClBrokerService::GetInstance() {
diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc
new file mode 100644
index 0000000..2b3ebd2
--- /dev/null
+++ b/chrome/browser/nacl_host/nacl_process_host.cc
@@ -0,0 +1,236 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "build/build_config.h"
+
+#include "chrome/browser/nacl_host/nacl_process_host.h"
+
+#if defined(OS_POSIX)
+#include <fcntl.h>
+#endif
+
+#include "base/command_line.h"
+#include "chrome/browser/nacl_host/nacl_broker_service.h"
+#include "chrome/browser/renderer_host/resource_message_filter.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/logging_chrome.h"
+#include "chrome/common/nacl_cmd_line.h"
+#include "chrome/common/nacl_messages.h"
+#include "chrome/common/render_messages.h"
+#include "ipc/ipc_switches.h"
+
+#if defined(OS_POSIX)
+#include "ipc/ipc_channel_posix.h"
+#endif
+
+NaClProcessHost::NaClProcessHost(
+ ResourceDispatcherHost *resource_dispatcher_host,
+ const std::wstring& url)
+ : ChildProcessHost(NACL_LOADER_PROCESS, resource_dispatcher_host),
+ resource_dispatcher_host_(resource_dispatcher_host),
+ reply_msg_(NULL),
+ descriptor_(0),
+ running_on_wow64_(false) {
+ set_name(url);
+#if defined(OS_WIN)
+ CheckIsWow64();
+#endif
+}
+
+NaClProcessHost::~NaClProcessHost() {
+ if (!reply_msg_)
+ return;
+
+ // OnProcessLaunched didn't get called because the process couldn't launch.
+ // Don't keep the renderer hanging.
+ reply_msg_->set_reply_error();
+ resource_message_filter_->Send(reply_msg_);
+}
+
+bool NaClProcessHost::Launch(ResourceMessageFilter* resource_message_filter,
+ const int descriptor,
+ IPC::Message* reply_msg) {
+#ifdef DISABLE_NACL
+ NOTIMPLEMENTED() << "Native Client disabled at build time";
+ return false;
+#else
+
+ // Create a connected socket
+ if (nacl::SocketPair(pair_) == -1)
+ return false;
+
+ // Launch the process
+ descriptor_ = descriptor;
+ if (!LaunchSelLdr()) {
+ nacl::Close(pair_[0]);
+ return false;
+ }
+
+ resource_message_filter_ = resource_message_filter;
+ reply_msg_ = reply_msg;
+
+ return true;
+#endif // DISABLE_NACL
+}
+
+bool NaClProcessHost::LaunchSelLdr() {
+ if (!CreateChannel())
+ return false;
+
+ // Build command line for nacl.
+ FilePath exe_path = GetChildPath(true);
+ if (exe_path.empty())
+ return false;
+
+ CommandLine* cmd_line = new CommandLine(exe_path);
+ nacl::CopyNaClCommandLineArguments(cmd_line);
+
+#if defined(OS_MACOSX)
+ // TODO(dspringer): NaCl is temporalrily disabled on the Mac by default, but
+ // it can be enabled with the --enable-nacl cmd-line switch. Remove this check
+ // when the security issues in the Mac PIC code are resolved.
+ if (!cmd_line->HasSwitch(switches::kEnableNaClOnMac))
+ return false;
+#endif
+
+ cmd_line->AppendSwitchWithValue(switches::kProcessType,
+ switches::kNaClLoaderProcess);
+
+ cmd_line->AppendSwitchWithValue(switches::kProcessChannelID,
+ ASCIIToWide(channel_id()));
+
+ // On Windows we might need to start the broker process to launch a new loader
+#if defined(OS_WIN)
+ if (running_on_wow64_) {
+ NaClBrokerService::GetInstance()->Init(resource_dispatcher_host_);
+ NaClBrokerService::GetInstance()->LaunchLoader(this,
+ ASCIIToWide(channel_id()));
+ } else
+#endif
+ ChildProcessHost::Launch(
+#if defined(OS_WIN)
+ FilePath(),
+#elif defined(OS_POSIX)
+ false,
+ base::environment_vector(),
+#endif
+ cmd_line);
+
+ return true;
+}
+
+void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) {
+ set_handle(handle);
+ OnProcessLaunched();
+}
+
+bool NaClProcessHost::DidChildCrash() {
+ if (running_on_wow64_) {
+ bool child_exited;
+ return base::DidProcessCrash(&child_exited, handle());
+ }
+ return ChildProcessHost::DidChildCrash();
+}
+
+void NaClProcessHost::OnProcessLaunched() {
+ nacl::FileDescriptor imc_handle;
+ base::ProcessHandle nacl_process_handle;
+#if NACL_WINDOWS
+ // Duplicate the IMC handle
+ // We assume the size of imc_handle has the same size as HANDLE, so the cast
+ // below is safe.
+ DCHECK(sizeof(HANDLE) == sizeof(imc_handle));
+ DuplicateHandle(base::GetCurrentProcessHandle(),
+ reinterpret_cast<HANDLE>(pair_[0]),
+ resource_message_filter_->handle(),
+ reinterpret_cast<HANDLE*>(&imc_handle),
+ GENERIC_READ | GENERIC_WRITE,
+ FALSE,
+ DUPLICATE_CLOSE_SOURCE);
+
+ // Duplicate the process handle
+ DuplicateHandle(base::GetCurrentProcessHandle(),
+ handle(),
+ resource_message_filter_->handle(),
+ &nacl_process_handle,
+ PROCESS_DUP_HANDLE,
+ FALSE,
+ 0);
+
+#else
+ int flags = fcntl(pair_[0], F_GETFD);
+ if (flags != -1) {
+ flags |= FD_CLOEXEC;
+ fcntl(pair_[0], F_SETFD, flags);
+ }
+ // No need to dup the imc_handle - we don't pass it anywhere else so
+ // it cannot be closed.
+ imc_handle.fd = pair_[0];
+ imc_handle.auto_close = true;
+
+ // We use pid as process handle on Posix
+ nacl_process_handle = handle();
+
+#endif
+
+ // Get the pid of the NaCl process
+ base::ProcessId nacl_process_id = base::GetProcId(handle());
+
+ ViewHostMsg_LaunchNaCl::WriteReplyParams(
+ reply_msg_, imc_handle, nacl_process_handle, nacl_process_id);
+ resource_message_filter_->Send(reply_msg_);
+ resource_message_filter_ = NULL;
+ reply_msg_ = NULL;
+
+ SendStartMessage();
+}
+
+void NaClProcessHost::SendStartMessage() {
+ nacl::FileDescriptor channel;
+#if defined(OS_WIN)
+ if (!DuplicateHandle(GetCurrentProcess(),
+ reinterpret_cast<HANDLE>(pair_[1]),
+ handle(),
+ reinterpret_cast<HANDLE*>(&channel),
+ GENERIC_READ | GENERIC_WRITE,
+ FALSE, DUPLICATE_CLOSE_SOURCE)) {
+ return;
+ }
+#else
+ channel.fd = dup(pair_[1]);
+ channel.auto_close = true;
+#endif
+ Send(new NaClProcessMsg_Start(descriptor_, channel));
+}
+
+void NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
+ NOTREACHED() << "Invalid message with type = " << msg.type();
+}
+
+URLRequestContext* NaClProcessHost::GetRequestContext(
+ uint32 request_id,
+ const ViewHostMsg_Resource_Request& request_data) {
+ return NULL;
+}
+
+#if defined(OS_WIN)
+// TODO(gregoryd): invoke CheckIsWow64 only once, not for each NaClProcessHost
+typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
+void NaClProcessHost::CheckIsWow64() {
+ LPFN_ISWOW64PROCESS fnIsWow64Process;
+
+ fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
+ GetModuleHandle(TEXT("kernel32")),
+ "IsWow64Process");
+
+ if (fnIsWow64Process != NULL) {
+ BOOL bIsWow64 = FALSE;
+ if (fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) {
+ if (bIsWow64) {
+ running_on_wow64_ = true;
+ }
+ }
+ }
+}
+#endif
diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h
new file mode 100644
index 0000000..bf96b83
--- /dev/null
+++ b/chrome/browser/nacl_host/nacl_process_host.h
@@ -0,0 +1,82 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NACL_HOST_NACL_PROCESS_HOST_H_
+#define CHROME_BROWSER_NACL_HOST_NACL_PROCESS_HOST_H_
+
+#include "build/build_config.h"
+
+#include "base/ref_counted.h"
+#include "chrome/common/child_process_host.h"
+#include "chrome/common/nacl_types.h"
+#include "native_client/src/shared/imc/nacl_imc.h"
+
+class ResourceMessageFilter;
+
+// Represents the browser side of the browser <--> NaCl communication
+// channel. There will be one NaClProcessHost per NaCl process
+// The browser is responsible for starting the NaCl process
+// when requested by the renderer.
+// After that, most of the communication is directly between NaCl plugin
+// running in the renderer and NaCl processes.
+class NaClProcessHost : public ChildProcessHost {
+ public:
+ NaClProcessHost(ResourceDispatcherHost *resource_dispatcher_host,
+ const std::wstring& url);
+ ~NaClProcessHost();
+
+ // Initialize the new NaCl process, returning true on success.
+ bool Launch(ResourceMessageFilter* resource_message_filter,
+ const int descriptor,
+ IPC::Message* reply_msg);
+
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ void OnProcessLaunchedByBroker(base::ProcessHandle handle);
+
+ protected:
+ virtual bool DidChildCrash();
+
+ private:
+ bool LaunchSelLdr();
+
+ void SendStartMessage();
+
+ virtual void OnProcessLaunched();
+
+ // ResourceDispatcherHost::Receiver implementation:
+ virtual URLRequestContext* GetRequestContext(
+ uint32 request_id,
+ const ViewHostMsg_Resource_Request& request_data);
+
+ virtual bool CanShutdown() { return true; }
+
+#if defined(OS_WIN)
+ // Check whether the browser process is running on WOW64 - Windows only
+ void CheckIsWow64();
+#endif
+
+ private:
+ ResourceDispatcherHost* resource_dispatcher_host_;
+
+ // The ResourceMessageFilter that requested this NaCl process. We use this
+ // for sending the reply once the process has started.
+ scoped_refptr<ResourceMessageFilter> resource_message_filter_;
+
+ // The reply message to send.
+ IPC::Message* reply_msg_;
+
+ // The socket pair for the NaCl process.
+ nacl::Handle pair_[2];
+
+ // The NaCl specific descriptor for this process.
+ int descriptor_;
+
+ // Windows platform flag
+ bool running_on_wow64_;
+
+ DISALLOW_COPY_AND_ASSIGN(NaClProcessHost);
+};
+
+#endif // CHROME_BROWSER_NACL_HOST_NACL_PROCESS_HOST_H_