diff options
29 files changed, 516 insertions, 42 deletions
@@ -40,7 +40,7 @@ deps = { "http://v8.googlecode.com/svn/trunk@2966", "src/native_client": - "http://nativeclient.googlecode.com/svn/trunk/src/native_client@730", + "http://nativeclient.googlecode.com/svn/trunk/src/native_client@795", "src/third_party/skia": "http://skia.googlecode.com/svn/trunk@341", diff --git a/base/format_macros.h b/base/format_macros.h index 4b713ef..383579f 100644 --- a/base/format_macros.h +++ b/base/format_macros.h @@ -37,9 +37,17 @@ #else // OS_WIN +#if !defined(PRId64) #define PRId64 "I64d" +#endif + +#if !defined(PRIu64) #define PRIu64 "I64u" +#endif + +#if !defined(PRIx64) #define PRIx64 "I64x" +#endif #define WidePRId64 L"I64d" #define WidePRIu64 L"I64u" diff --git a/chrome/app/chrome_dll_main.cc b/chrome/app/chrome_dll_main.cc index ecf2640..63dcc70 100644 --- a/chrome/app/chrome_dll_main.cc +++ b/chrome/app/chrome_dll_main.cc @@ -80,6 +80,7 @@ extern int BrowserMain(const MainFunctionParams&); extern int RendererMain(const MainFunctionParams&); extern int PluginMain(const MainFunctionParams&); extern int WorkerMain(const MainFunctionParams&); +extern int NaClMain(const MainFunctionParams&); extern int UtilityMain(const MainFunctionParams&); extern int ProfileImportMain(const MainFunctionParams&); extern int ZygoteMain(const MainFunctionParams&); @@ -563,6 +564,8 @@ int ChromeMain(int argc, char** argv) { #endif } else if (process_type == switches::kWorkerProcess) { rv = WorkerMain(main_params); + } else if (process_type == switches::kNaClProcess) { + rv = NaClMain(main_params); } else if (process_type == switches::kZygoteProcess) { #if defined(OS_LINUX) if (ZygoteMain(main_params)) { diff --git a/chrome/browser/nacl_process_host.cc b/chrome/browser/nacl_process_host.cc new file mode 100644 index 0000000..72db561 --- /dev/null +++ b/chrome/browser/nacl_process_host.cc @@ -0,0 +1,187 @@ +// 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_process_host.h" + +#if defined(OS_POSIX) +#include <fcntl.h> +#endif + +#if defined(OS_POSIX) +#include "base/global_descriptors_posix.h" +#endif +#include "base/path_service.h" +#include "base/process_util.h" +#include "chrome/browser/renderer_host/resource_message_filter.h" +#include "chrome/common/chrome_descriptors.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/logging_chrome.h" +#include "chrome/common/nacl_messages.h" +#include "ipc/ipc_switches.h" + +#if defined(OS_WIN) +#include "chrome/browser/sandbox_policy.h" +#endif + +#if defined(OS_POSIX) +#include "ipc/ipc_channel_posix.h" +#endif + +NaClProcessHost::NaClProcessHost( + ResourceDispatcherHost *resource_dispatcher_host) + : ChildProcessHost(NACL_PROCESS, resource_dispatcher_host), + resource_dispatcher_host_(resource_dispatcher_host) { +} + +bool NaClProcessHost::Launch(ResourceMessageFilter* renderer_msg_filter, + const int descriptor, + nacl::FileDescriptor* handle) { + nacl::Handle pair[2]; + bool success = false; + // Create a connected socket + if (nacl::SocketPair(pair) == -1) { + NATIVE_HANDLE(*handle) = nacl::kInvalidHandle; + return false; + } + + // Launch the process + success = LaunchSelLdr(renderer_msg_filter, descriptor, pair[1]); + + if (!success) { + nacl::Close(pair[0]); + NATIVE_HANDLE(*handle) = nacl::kInvalidHandle; + return false; + } + + nacl::Handle duplicate_handle = nacl::kInvalidHandle; +#if NACL_WINDOWS + DuplicateHandle(base::GetCurrentProcessHandle(), + reinterpret_cast<HANDLE>(pair[0]), + renderer_msg_filter->handle(), + reinterpret_cast<HANDLE*>(&duplicate_handle), + GENERIC_READ | GENERIC_WRITE, + FALSE, + DUPLICATE_CLOSE_SOURCE); + *handle = duplicate_handle; +#else + duplicate_handle = pair[0]; + int flags = fcntl(duplicate_handle, F_GETFD); + if (flags != -1) { + flags |= FD_CLOEXEC; + fcntl(duplicate_handle, F_SETFD, flags); + } + // No need to dup the handle - we don't pass it anywhere else so + // it cannot be closed. + handle->fd = duplicate_handle; + handle->auto_close = true; +#endif + + return true; +} + +bool NaClProcessHost::LaunchSelLdr(ResourceMessageFilter* renderer_msg_filter, + const int descriptor, + const nacl::Handle handle) { + if (!CreateChannel()) + return false; + + // Build command line for nacl. + const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); + std::wstring exe_path = + browser_command_line.GetSwitchValue(switches::kBrowserSubprocessPath); + if (exe_path.empty() && !PathService::Get(base::FILE_EXE, &exe_path)) + return false; + + CommandLine cmd_line(exe_path); + if (logging::DialogsAreSuppressed()) + cmd_line.AppendSwitch(switches::kNoErrorDialogs); + + // propagate the following switches to the plugin command line (along with + // any associated values) if present in the browser command line + // TODO(gregoryd): check which flags of those below can be supported. + static const wchar_t* const switch_names[] = { + switches::kNoSandbox, + switches::kTestSandbox, + switches::kDisableBreakpad, + switches::kFullMemoryCrashReport, + switches::kEnableLogging, + switches::kDisableLogging, + switches::kLoggingLevel, + switches::kEnableDCHECK, + switches::kSilentDumpOnDCHECK, + switches::kMemoryProfiling, + }; + + for (size_t i = 0; i < arraysize(switch_names); ++i) { + if (browser_command_line.HasSwitch(switch_names[i])) { + cmd_line.AppendSwitchWithValue( + switch_names[i], + browser_command_line.GetSwitchValue(switch_names[i])); + } + } + + cmd_line.AppendSwitchWithValue(switches::kProcessType, + switches::kNaClProcess); + + cmd_line.AppendSwitchWithValue(switches::kProcessChannelID, + ASCIIToWide(channel_id())); + + base::ProcessHandle process = 0; +#if defined(OS_WIN) + process = sandbox::StartProcess(&cmd_line); +#else + base::file_handle_mapping_vector fds_to_map; + const int ipcfd = channel().GetClientFileDescriptor(); + if (ipcfd > -1) + fds_to_map.push_back(std::pair<int, int>( + ipcfd, kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor)); + base::LaunchApp(cmd_line.argv(), fds_to_map, false, &process); +#endif + + if (!process) + return false; + SetHandle(process); + + // send a message with duplicated handle to sel_ldr + return SendStartMessage(process, descriptor, handle); +} + +bool NaClProcessHost::SendStartMessage(base::ProcessHandle process, + int descriptor, + nacl::Handle handle) { + nacl::FileDescriptor channel; +#if defined(OS_WIN) + if (!DuplicateHandle(GetCurrentProcess(), + reinterpret_cast<HANDLE>(handle), + process, + reinterpret_cast<HANDLE*>(&channel), + GENERIC_READ | GENERIC_WRITE, + FALSE, DUPLICATE_CLOSE_SOURCE)) { + return false; + } +#else + channel.fd = dup(handle); + channel.auto_close = true; +#endif + NaClProcessMsg_Start* msg = new NaClProcessMsg_Start(descriptor, + channel); + + if (!Send(msg)) { + return false; + } + return true; +} + +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; +} + diff --git a/chrome/browser/nacl_process_host.h b/chrome/browser/nacl_process_host.h new file mode 100644 index 0000000..59de526 --- /dev/null +++ b/chrome/browser/nacl_process_host.h @@ -0,0 +1,55 @@ +// 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_PROCESS_HOST_H_ +#define CHROME_BROWSER_NACL_PROCESS_HOST_H_ + +#include "build/build_config.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: + explicit NaClProcessHost(ResourceDispatcherHost *resource_dispatcher_host); + ~NaClProcessHost() {} + + // Initialize the new NaCl process, returning true on success. + bool Launch(ResourceMessageFilter* renderer_msg_filter, + const int descriptor, + nacl::FileDescriptor *handle); + + virtual void OnMessageReceived(const IPC::Message& msg); + + private: + bool LaunchSelLdr(ResourceMessageFilter* renderer_msg_filter, + const int descriptor, + const nacl::Handle handle); + + bool SendStartMessage(base::ProcessHandle process, + int descriptor, + nacl::Handle handle); + + // ResourceDispatcherHost::Receiver implementation: + virtual URLRequestContext* GetRequestContext( + uint32 request_id, + const ViewHostMsg_Resource_Request& request_data); + + virtual bool CanShutdown() { return true; } + + private: + ResourceDispatcherHost* resource_dispatcher_host_; + + DISALLOW_COPY_AND_ASSIGN(NaClProcessHost); +}; + +#endif // CHROME_BROWSER_NACL_PROCESS_HOST_H_ diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc index 42a67e9..5c5a8bb 100644 --- a/chrome/browser/plugin_service.cc +++ b/chrome/browser/plugin_service.cc @@ -23,6 +23,7 @@ #include "chrome/common/notification_type.h" #include "chrome/common/notification_service.h" #include "chrome/common/render_messages.h" +#include "native_client/src/trusted/plugin/nacl_entry_points.h" #include "webkit/glue/plugins/plugin_constants_win.h" #include "webkit/glue/plugins/plugin_list.h" @@ -44,6 +45,8 @@ PluginService::PluginService() NPAPI::PluginList::Singleton()->AddExtraPluginPath( FilePath::FromWStringHack(path)); } + if (command_line->HasSwitch(switches::kInternalNaCl)) + RegisterInternalNaClPlugin(); #if defined(OS_WIN) hkcu_key_.Create( diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index fb91a80..43482f1 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -326,6 +326,7 @@ bool BrowserRenderProcessHost::Init() { switches::kDisableAudio, switches::kSimpleDataSource, switches::kEnableBenchmarking, + switches::kInternalNaCl, switches::kEnableDatabases, }; diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index 0b8a923..3091033 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -15,6 +15,7 @@ #include "chrome/browser/chrome_thread.h" #include "chrome/browser/extensions/extension_message_service.h" #include "chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h" +#include "chrome/browser/nacl_process_host.h" #include "chrome/browser/net/chrome_url_request_context.h" #include "chrome/browser/net/dns_global.h" #include "chrome/browser/plugin_service.h" @@ -295,6 +296,7 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& msg) { OnReceiveContextMenuMsg(msg)) IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenChannelToPlugin, OnOpenChannelToPlugin) + IPC_MESSAGE_HANDLER(ViewHostMsg_LaunchNaCl, OnLaunchNaCl) IPC_MESSAGE_HANDLER(ViewHostMsg_CreateDedicatedWorker, OnCreateDedicatedWorker) IPC_MESSAGE_HANDLER(ViewHostMsg_CancelCreateDedicatedWorker, @@ -585,6 +587,12 @@ void ResourceMessageFilter::OnOpenChannelToPlugin(const GURL& url, this, url, mime_type, locale, reply_msg); } +void ResourceMessageFilter::OnLaunchNaCl(int channel_descriptor, + nacl::FileDescriptor* handle) { + NaClProcessHost* nacl_host = new NaClProcessHost(resource_dispatcher_host_); + nacl_host->Launch(this, channel_descriptor, handle); +} + void ResourceMessageFilter::OnCreateDedicatedWorker(const GURL& url, int render_view_route_id, int* route_id) { diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h index 6b93eee..ca37294 100644 --- a/chrome/browser/renderer_host/resource_message_filter.h +++ b/chrome/browser/renderer_host/resource_message_filter.h @@ -25,6 +25,7 @@ #include "chrome/browser/renderer_host/render_widget_helper.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/common/modal_dialog_event.h" +#include "chrome/common/nacl_types.h" #include "chrome/common/notification_registrar.h" #include "chrome/common/transport_dib.h" #include "ipc/ipc_channel_proxy.h" @@ -154,6 +155,8 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, const std::string& mime_type, const std::wstring& locale, IPC::Message* reply_msg); + void OnLaunchNaCl(int channel_descriptor, + nacl::FileDescriptor* handle); void OnCreateDedicatedWorker(const GURL& url, int render_view_route_id, int* route_id); diff --git a/chrome/browser/sandbox_policy.cc b/chrome/browser/sandbox_policy.cc index 13f4ee2..784e5a7 100644 --- a/chrome/browser/sandbox_policy.cc +++ b/chrome/browser/sandbox_policy.cc @@ -359,6 +359,8 @@ base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line, type = ChildProcessInfo::PLUGIN_PROCESS; } else if (type_str == switches::kWorkerProcess) { type = ChildProcessInfo::WORKER_PROCESS; + } else if (type_str == switches::kNaClProcess) { + type = ChildProcessInfo::NACL_PROCESS; } else if (type_str == switches::kUtilityProcess) { type = ChildProcessInfo::UTILITY_PROCESS; } else { @@ -371,8 +373,10 @@ base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line, (type != ChildProcessInfo::PLUGIN_PROCESS || browser_command_line.HasSwitch(switches::kSafePlugins)); #if !defined (GOOGLE_CHROME_BUILD) - if (browser_command_line.HasSwitch(switches::kInProcessPlugins)) { + if (browser_command_line.HasSwitch(switches::kInProcessPlugins) || + browser_command_line.HasSwitch(switches::kInternalNaCl)) { // In process plugins won't work if the sandbox is enabled. + // The internal NaCl plugin doesn't work in the sandbox for now. in_sandbox = false; } #endif @@ -394,6 +398,8 @@ base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line, sandbox::TargetPolicy* policy = broker_service->CreatePolicy(); bool on_sandbox_desktop = false; + // TODO(gregoryd): try locked-down policy for sel_ldr after we fix IMC. + // TODO(gregoryd): do we need a new desktop for sel_ldr? if (type == ChildProcessInfo::PLUGIN_PROCESS) { if (!AddPolicyForPlugin(cmd_line, policy)) return 0; diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index e381018..98c90e1 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -108,7 +108,26 @@ '../views/grid_layout_unittest.cc', ], 'conditions': [ + ['OS=="win"', { + 'nacl_defines': [ + 'NACL_WINDOWS=1', + 'NACL_LINUX=0', + 'NACL_OSX=0', + ], + },], + ['OS=="linux"', { + 'nacl_defines': [ + 'NACL_WINDOWS=0', + 'NACL_LINUX=1', + 'NACL_OSX=0', + ], + },], ['OS=="mac"', { + 'nacl_defines': [ + 'NACL_WINDOWS=0', + 'NACL_LINUX=0', + 'NACL_OSX=1', + ], 'conditions': [ ['branding=="Chrome"', { 'mac_bundle_id': 'com.google.Chrome', @@ -128,6 +147,20 @@ 'chrome_personalization%': 0, 'use_syncapi_stub%': 1, }], # OS=="win" + ['target_arch=="ia32"', { + 'nacl_defines': [ + # TODO(gregoryd): consider getting this from NaCl's common.gypi + 'NACL_TARGET_SUBARCH=32', + 'NACL_BUILD_SUBARCH=32', + ], + }], + ['target_arch=="x64"', { + 'nacl_defines': [ + # TODO(gregoryd): consider getting this from NaCl's common.gypi + 'NACL_TARGET_SUBARCH=64', + 'NACL_BUILD_SUBARCH=64', + ], + }], ], # conditions }, # variables 'target_defaults': { @@ -597,6 +630,8 @@ 'common/sandbox_init_wrapper.h', 'common/security_filter_peer.cc', 'common/security_filter_peer.h', + 'common/nacl_messages.h', + 'common/nacl_messages_internal.h', 'common/sqlite_compiled_statement.cc', 'common/sqlite_compiled_statement.h', 'common/sqlite_utils.cc', @@ -711,6 +746,9 @@ '..', '<(INTERMEDIATE_DIR)', ], + 'defines': [ + '<@(nacl_defines)', + ], 'sources': [ # All .cc, .h, .m, and .mm files under browser except for tests and # mocks. @@ -1835,6 +1873,8 @@ 'browser/search_engines/template_url_prepopulate_data.h', 'browser/search_engines/template_url_table_model.cc', 'browser/search_engines/template_url_table_model.h', + 'browser/nacl_process_host.cc', + 'browser/nacl_process_host.h', 'browser/session_startup_pref.cc', 'browser/session_startup_pref.h', 'browser/sessions/base_session_service.cc', @@ -2877,11 +2917,57 @@ ], }, { + 'target_name': 'nacl', + 'type': '<(library)', + 'msvs_guid': '83E86DAF-5763-4711-AD34-5FDAE395560C', + 'dependencies': [ + 'common', + 'chrome_resources', + 'chrome_strings', + '../third_party/npapi/npapi.gyp:npapi', + '../webkit/webkit.gyp:glue', + '../native_client/src/trusted/plugin/plugin_chrome.gyp:npGoogleNaClPluginChrome', + '../native_client/src/trusted/service_runtime/service_runtime.gyp:sel', + '../native_client/src/trusted/validator_x86/validator_x86.gyp:ncvalidate', + '../native_client/src/trusted/platform_qualify/platform_qualify.gyp:platform_qual_lib', + ], + 'include_dirs': [ + '<(INTERMEDIATE_DIR)', + ], + 'defines': [ + 'NACL_BLOCK_SHIFT=5', + 'NACL_BLOCK_SIZE=32', + '<@(nacl_defines)', + ], + 'sources': [ + # All .cc, .h, .m, and .mm files under nacl except for tests and + # mocks. + 'nacl/sel_main.cc', + 'nacl/nacl_main.cc', + 'nacl/nacl_thread.cc', + 'nacl/nacl_thread.h', + ], + # TODO(gregoryd): consider switching NaCl to use Chrome OS defines + 'conditions': [ + ['OS=="win"', { + 'defines': [ + '__STD_C', + '_CRT_SECURE_NO_DEPRECATE', + '_SCL_SECURE_NO_DEPRECATE', + ], + 'include_dirs': [ + 'third_party/wtl/include', + ], + },], + ], + }, + { 'target_name': 'renderer', 'type': '<(library)', 'msvs_guid': '9301A569-5D2B-4D11-9332-B1E30AEACB8D', 'dependencies': [ 'common', + 'nacl', 'plugin', 'chrome_resources', 'chrome_strings', @@ -2896,6 +2982,9 @@ 'include_dirs': [ '..', ], + 'defines': [ + '<@(nacl_defines)', + ], 'sources': [ # TODO(jrg): to link ipc_tests, these files need to be in renderer.a. # But app/ is the wrong directory for them. @@ -3373,6 +3462,8 @@ 'infoplist_strings_tool', # Bring in pdfsqueeze and run it on all pdfs '../build/temp_gyp/pdfsqueeze.gyp:pdfsqueeze', + # This library provides the real implementation for NaClSyscallSeg + '../native_client/src/trusted/service_runtime/arch/x86_32/service_runtime_x86_32.gyp:service_runtime_x86_32_chrome' ], 'rules': [ { diff --git a/chrome/common/child_process_info.h b/chrome/common/child_process_info.h index 250ff57..c99b2c0 100644 --- a/chrome/common/child_process_info.h +++ b/chrome/common/child_process_info.h @@ -17,6 +17,7 @@ class ChildProcessInfo { RENDER_PROCESS, PLUGIN_PROCESS, WORKER_PROCESS, + NACL_PROCESS, UTILITY_PROCESS, PROFILE_IMPORT_PROCESS, ZYGOTE_PROCESS, diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 762d524..e79f345 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -71,6 +71,9 @@ const wchar_t kPluginProcess[] = L"plugin"; // Causes the process to run as a worker subprocess. const wchar_t kWorkerProcess[] = L"worker"; +// Causes the process to run as a NativeClient's sel_ldr subprocess. +const wchar_t kNaClProcess[] = L"nacl"; + // Causes the process to run as a utility subprocess. const wchar_t kUtilityProcess[] = L"utility"; @@ -367,6 +370,9 @@ const wchar_t kEnableRemoteFonts[] = L"enable-remote-fonts"; // Use the low fragmentation heap for the CRT. const wchar_t kUseLowFragHeapCrt[] = L"use-lf-heap"; +// Runs the Native Client inside the renderer process. +const wchar_t kInternalNaCl[] = L"internal-nacl"; + #ifndef NDEBUG // Debug only switch to specify which gears plugin dll to load. const wchar_t kGearsPluginPathOverride[] = L"gears-plugin-path"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 5602c58..3696066 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -30,6 +30,7 @@ extern const wchar_t kZygoteProcess[]; extern const wchar_t kBrowserSubprocessPath[]; extern const wchar_t kPluginProcess[]; extern const wchar_t kWorkerProcess[]; +extern const wchar_t kNaClProcess[]; extern const wchar_t kUtilityProcess[]; extern const wchar_t kProfileImportProcess[]; extern const wchar_t kSingleProcess[]; @@ -133,6 +134,8 @@ extern const wchar_t kEnableRemoteFonts[]; extern const wchar_t kUseLowFragHeapCrt[]; +extern const wchar_t kInternalNaCl[]; + #ifndef NDEBUG extern const wchar_t kGearsPluginPathOverride[]; #endif diff --git a/chrome/common/nacl_messages.h b/chrome/common/nacl_messages.h new file mode 100644 index 0000000..8d360dd --- /dev/null +++ b/chrome/common/nacl_messages.h @@ -0,0 +1,19 @@ +// 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. + +// Defines messages between the browser and NaCl process. + +#ifndef CHROME_COMMON_NACL_MESSAGES_H_ +#define CHROME_COMMON_NACL_MESSAGES_H_ + +#include <string> + +#include "base/basictypes.h" +#include "ipc/ipc_message_utils.h" + +#define MESSAGES_INTERNAL_FILE "chrome/common/nacl_messages_internal.h" +#include "ipc/ipc_message_macros.h" + +#endif // CHROME_COMMON_NACL_MESSAGES_H_ + diff --git a/chrome/common/nacl_messages_internal.h b/chrome/common/nacl_messages_internal.h new file mode 100644 index 0000000..3794255 --- /dev/null +++ b/chrome/common/nacl_messages_internal.h @@ -0,0 +1,18 @@ +// 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 "chrome/common/nacl_types.h" +#include "ipc/ipc_message_macros.h" + +//----------------------------------------------------------------------------- +// NaClProcess messages +// These are messages sent from the browser to the NaCl process. +IPC_BEGIN_MESSAGES(NaClProcess) + // Tells the NaCl process to start. + IPC_MESSAGE_CONTROL2(NaClProcessMsg_Start, + int /* descriptor id */, + nacl::FileDescriptor /* handle value */) + +IPC_END_MESSAGES(NaClProcess) + diff --git a/chrome/common/nacl_types.h b/chrome/common/nacl_types.h new file mode 100644 index 0000000..394edd3 --- /dev/null +++ b/chrome/common/nacl_types.h @@ -0,0 +1,21 @@ +// 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. + +// Handle passing definitions for NaCl +#ifndef CHROME_COMMON_NACL_TYPES_H_ +#define CHROME_COMMON_NACL_TYPES_H_ + +// TODO(gregoryd): add a Windows definition for base::FileDescriptor, +// replace the macros with inline functions. +namespace nacl { +#if defined(OS_WIN) +typedef HANDLE FileDescriptor; +#define NATIVE_HANDLE(desc) (desc) +#elif defined(OS_POSIX) +typedef base::FileDescriptor FileDescriptor; +#define NATIVE_HANDLE(desc) ((desc).fd) +#endif +} + +#endif // CHROME_COMMON_NACL_TYPES_H_ diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 22ba42a..ba9b8e3 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -22,6 +22,7 @@ #include "base/values.h" #include "chrome/common/css_colors.h" #include "chrome/common/extensions/update_manifest.h" +#include "chrome/common/nacl_types.h" #include "chrome/common/notification_type.h" #include "chrome/common/transport_dib.h" #include "chrome/common/view_types.h" @@ -1101,6 +1102,14 @@ IPC_BEGIN_MESSAGES(ViewHost) IPC::ChannelHandle /* handle to channel */, WebPluginInfo /* info */) + // A renderer sends this to the browser process when it wants to start + // a new instance of the Native Client process. The browser will launch + // the process and return a handle to an IMC channel. + IPC_SYNC_MESSAGE_CONTROL1_1(ViewHostMsg_LaunchNaCl, + int /* channel number */, + nacl::FileDescriptor /* handle - one side + of a socket pair */) + #if defined(OS_LINUX) // A renderer sends this when it needs a browser-side widget for // hosting a windowed plugin. id is the XID of the plugin window, for which diff --git a/chrome/common/sandbox_init_wrapper.cc b/chrome/common/sandbox_init_wrapper.cc index c296ff8..14006ed 100644 --- a/chrome/common/sandbox_init_wrapper.cc +++ b/chrome/common/sandbox_init_wrapper.cc @@ -27,6 +27,7 @@ void SandboxInitWrapper::InitializeSandbox(const CommandLine& command_line, if (!command_line.HasSwitch(switches::kNoSandbox)) { if ((process_type == switches::kRendererProcess) || (process_type == switches::kWorkerProcess) || + (process_type == switches::kNaClProcess) || (process_type == switches::kUtilityProcess) || (process_type == switches::kPluginProcess && command_line.HasSwitch(switches::kSafePlugins))) { diff --git a/chrome/nacl/nacl_main.cc b/chrome/nacl/nacl_main.cc index f519748..0516495 100644 --- a/chrome/nacl/nacl_main.cc +++ b/chrome/nacl/nacl_main.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// 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. diff --git a/chrome/nacl/nacl_thread.cc b/chrome/nacl/nacl_thread.cc index ff4f508..3ed7c93 100644 --- a/chrome/nacl/nacl_thread.cc +++ b/chrome/nacl/nacl_thread.cc @@ -1,10 +1,9 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// 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 "chrome/nacl/nacl_thread.h" -#include "build/build_config.h" #include "chrome/common/notification_service.h" #include "chrome/common/nacl_messages.h" #include "native_client/src/trusted/service_runtime/include/sys/nacl_imc_api.h" @@ -27,7 +26,7 @@ void NaClThread::OnControlMessageReceived(const IPC::Message& msg) { IPC_END_MESSAGE_MAP() } -void NaClThread::OnStartSelLdr(const int channel_descriptor, - const nacl::FileDescriptor handle) { +void NaClThread::OnStartSelLdr(int channel_descriptor, + nacl::FileDescriptor handle) { SelMain(channel_descriptor, NATIVE_HANDLE(handle)); } diff --git a/chrome/nacl/nacl_thread.h b/chrome/nacl/nacl_thread.h index a69ce3a..fd8fe76 100644 --- a/chrome/nacl/nacl_thread.h +++ b/chrome/nacl/nacl_thread.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// 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. @@ -23,13 +23,10 @@ class NaClThread : public ChildThread { private: virtual void OnControlMessageReceived(const IPC::Message& msg); - void OnStartSelLdr(const int channel_descriptor, - const nacl::FileDescriptor handle); - // TODO(gregoryd): do we need to override Cleanup as in PluginThread? - - scoped_ptr<NotificationService> notification_service_; + void OnStartSelLdr(int channel_descriptor, nacl::FileDescriptor handle); - DISALLOW_EVIL_CONSTRUCTORS(NaClThread); + // TODO(gregoryd): do we need to override Cleanup as in PluginThread? + DISALLOW_COPY_AND_ASSIGN(NaClThread); }; #endif // CHROME_NACL_NACL_THREAD_H_ diff --git a/chrome/nacl/sel_main.cc b/chrome/nacl/sel_main.cc index 7174706..7258205 100644 --- a/chrome/nacl/sel_main.cc +++ b/chrome/nacl/sel_main.cc @@ -1,9 +1,7 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// 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 "native_client/src/include/portability.h" #if NACL_OSX diff --git a/chrome/renderer/render_process.cc b/chrome/renderer/render_process.cc index 610e5d3..0c579ea 100644 --- a/chrome/renderer/render_process.cc +++ b/chrome/renderer/render_process.cc @@ -25,11 +25,13 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/render_messages.h" +#include "chrome/common/nacl_types.h" #include "chrome/common/transport_dib.h" #include "chrome/renderer/render_view.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_message_utils.h" #include "media/base/media.h" +#include "native_client/src/trusted/plugin/nacl_entry_points.h" #include "webkit/glue/webkit_glue.h" //----------------------------------------------------------------------------- @@ -80,6 +82,9 @@ RenderProcess::RenderProcess() StatisticsRecorder::set_dump_on_exit(true); } + if (command_line.HasSwitch(switches::kInternalNaCl)) + RegisterInternalNaClPlugin(RenderProcess::LaunchNaClProcess); + FilePath module_path; initialized_media_library_ = PathService::Get(base::DIR_MODULE, &module_path) && @@ -112,6 +117,19 @@ bool RenderProcess::InProcessPlugins() { #endif } +bool RenderProcess::LaunchNaClProcess(int imc_fd, + nacl::Handle* handle) { + // TODO(gregoryd): nacl::FileDescriptor will be soon merged with + // base::FileDescriptor + nacl::FileDescriptor descriptor; + if (!RenderThread::current()->Send( + new ViewHostMsg_LaunchNaCl(imc_fd, &descriptor))) { + return false; + } + *handle = NATIVE_HANDLE(descriptor); + return true; +} + // ----------------------------------------------------------------------------- // Platform specific code for dealing with bitmap transport... diff --git a/chrome/renderer/render_process.h b/chrome/renderer/render_process.h index d445fbe..0ab9996 100644 --- a/chrome/renderer/render_process.h +++ b/chrome/renderer/render_process.h @@ -8,6 +8,7 @@ #include "base/timer.h" #include "chrome/common/child_process.h" #include "chrome/renderer/render_thread.h" +#include "native_client/src/shared/imc/nacl_imc.h" #include "skia/ext/platform_canvas.h" namespace gfx { @@ -51,6 +52,10 @@ class RenderProcess : public ChildProcess { // Just like in_process_plugins(), but called before RenderProcess is created. static bool InProcessPlugins(); + // Sends a message to the browser process asking to launch a new NaCl process. + // Called from NaCl plugin code. + static bool LaunchNaClProcess(int imc_fd, nacl::Handle *handle); + private: // Look in the shared memory cache for a suitable object to reuse. // result: (output) the memory found diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 842dfc0..2d2407d 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -2357,7 +2357,13 @@ webkit_glue::WebPluginDelegate* RenderView::CreatePluginDelegate( else mime_type_to_use = &mime_type; - if (RenderProcess::current()->in_process_plugins()) { + bool in_process_plugin = RenderProcess::current()->in_process_plugins(); + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kInternalNaCl)) { + if (mime_type == "application/x-nacl-srpc") { + in_process_plugin = true; + } + } + if (in_process_plugin) { #if defined(OS_WIN) // In-proc plugins aren't supported on Linux or Mac. return WebPluginDelegateImpl::Create( path, *mime_type_to_use, gfx::NativeViewFromId(host_window_)); diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h index 15d5297..fd0c064 100644 --- a/ipc/ipc_message_utils.h +++ b/ipc/ipc_message_utils.h @@ -44,6 +44,7 @@ enum IPCMessageStart { WorkerProcessHostMsgStart, WorkerMsgStart, WorkerHostMsgStart, + NaClProcessMsgStart, // NOTE: When you add a new message class, also update // IPCStatusView::IPCStatusView to ensure logging works. // NOTE: this enum is used by IPC_MESSAGE_MACRO to generate a unique message diff --git a/webkit/glue/plugins/plugin_lib.h b/webkit/glue/plugins/plugin_lib.h index ed523c12..e8bb44a 100644 --- a/webkit/glue/plugins/plugin_lib.h +++ b/webkit/glue/plugins/plugin_lib.h @@ -61,6 +61,8 @@ class PluginLib : public base::RefCounted<PluginLib> { // supports. const WebPluginInfo& plugin_info() { return web_plugin_info_; } + bool internal() { return internal_; } + // // NPAPI functions // @@ -91,7 +93,7 @@ class PluginLib : public base::RefCounted<PluginLib> { void Shutdown(); private: - bool internal_; // Whether this an internal plugin. + bool internal_; // True for plugins that are built-in into chrome binaries. WebPluginInfo web_plugin_info_; // supported mime types, description base::NativeLibrary library_; // the opened library reference NPPluginFuncs plugin_funcs_; // the struct of plugin side functions diff --git a/webkit/glue/plugins/webplugin_delegate_impl_win.cc b/webkit/glue/plugins/webplugin_delegate_impl_win.cc index 1f13cf8..9d8ed45 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_win.cc +++ b/webkit/glue/plugins/webplugin_delegate_impl_win.cc @@ -326,35 +326,40 @@ void WebPluginDelegateImpl::PluginDestroyed() { void WebPluginDelegateImpl::PlatformInitialize() { plugin_->SetWindow(windowed_handle_); - if (windowless_) { + + if (windowless_ && !instance_->plugin_lib()->internal()) { CreateDummyWindowForActivation(); handle_event_pump_messages_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); plugin_->SetWindowlessPumpEvent(handle_event_pump_messages_event_); } - // Windowless plugins call the WindowFromPoint API and passes the result of - // that to the TrackPopupMenu API call as the owner window. This causes the - // API to fail as the API expects the window handle to live on the same thread - // as the caller. It works in the other browsers as the plugin lives on the - // browser thread. Our workaround is to intercept the TrackPopupMenu API and - // replace the window handle with the dummy activation window. - if (windowless_ && !g_iat_patch_track_popup_menu.Pointer()->is_patched()) { - g_iat_patch_track_popup_menu.Pointer()->Patch( - GetPluginPath().value().c_str(), "user32.dll", "TrackPopupMenu", - WebPluginDelegateImpl::TrackPopupMenuPatch); - } + // We cannot patch internal plugins as they are not shared libraries. + if (!instance_->plugin_lib()->internal()) { + // Windowless plugins call the WindowFromPoint API and passes the result of + // that to the TrackPopupMenu API call as the owner window. This causes the + // API to fail as the API expects the window handle to live on the same + // thread as the caller. It works in the other browsers as the plugin lives + // on the browser thread. Our workaround is to intercept the TrackPopupMenu + // API and replace the window handle with the dummy activation window. + if (windowless_ && !g_iat_patch_track_popup_menu.Pointer()->is_patched()) { + g_iat_patch_track_popup_menu.Pointer()->Patch( + GetPluginPath().value().c_str(), "user32.dll", "TrackPopupMenu", + WebPluginDelegateImpl::TrackPopupMenuPatch); + } - // Windowless plugins can set cursors by calling the SetCursor API. This - // works because the thread inputs of the browser UI thread and the plugin - // thread are attached. We intercept the SetCursor API for windowless plugins - // and remember the cursor being set. This is shipped over to the browser - // in the HandleEvent call, which ensures that the cursor does not change - // when a windowless plugin instance changes the cursor in a background tab. - if (windowless_ && !g_iat_patch_set_cursor.Pointer()->is_patched() && - (quirks_ & PLUGIN_QUIRK_PATCH_SETCURSOR)) { - g_iat_patch_set_cursor.Pointer()->Patch( - GetPluginPath().value().c_str(), "user32.dll", "SetCursor", - WebPluginDelegateImpl::SetCursorPatch); + // Windowless plugins can set cursors by calling the SetCursor API. This + // works because the thread inputs of the browser UI thread and the plugin + // thread are attached. We intercept the SetCursor API for windowless + // plugins and remember the cursor being set. This is shipped over to the + // browser in the HandleEvent call, which ensures that the cursor does not + // change when a windowless plugin instance changes the cursor + // in a background tab. + if (windowless_ && !g_iat_patch_set_cursor.Pointer()->is_patched() && + (quirks_ & PLUGIN_QUIRK_PATCH_SETCURSOR)) { + g_iat_patch_set_cursor.Pointer()->Patch( + GetPluginPath().value().c_str(), "user32.dll", "SetCursor", + WebPluginDelegateImpl::SetCursorPatch); + } } // On XP, WMP will use its old UI unless a registry key under HKLM has the |