OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/nacl/browser/nacl_process_host.h" | 5 #include "components/nacl/browser/nacl_process_host.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 30 matching lines...) Expand all Loading... |
41 #include "content/public/common/content_switches.h" | 41 #include "content/public/common/content_switches.h" |
42 #include "content/public/common/process_type.h" | 42 #include "content/public/common/process_type.h" |
43 #include "ipc/ipc_channel.h" | 43 #include "ipc/ipc_channel.h" |
44 #include "ipc/ipc_switches.h" | 44 #include "ipc/ipc_switches.h" |
45 #include "native_client/src/shared/imc/nacl_imc_c.h" | 45 #include "native_client/src/shared/imc/nacl_imc_c.h" |
46 #include "net/base/net_util.h" | 46 #include "net/base/net_util.h" |
47 #include "net/socket/tcp_listen_socket.h" | 47 #include "net/socket/tcp_listen_socket.h" |
48 #include "ppapi/host/host_factory.h" | 48 #include "ppapi/host/host_factory.h" |
49 #include "ppapi/host/ppapi_host.h" | 49 #include "ppapi/host/ppapi_host.h" |
50 #include "ppapi/proxy/ppapi_messages.h" | 50 #include "ppapi/proxy/ppapi_messages.h" |
51 #include "ppapi/shared_impl/ppapi_nacl_channel_args.h" | 51 #include "ppapi/shared_impl/ppapi_nacl_plugin_args.h" |
52 #include "ppapi/shared_impl/ppapi_switches.h" | 52 #include "ppapi/shared_impl/ppapi_switches.h" |
53 | 53 |
54 #if defined(OS_POSIX) | 54 #if defined(OS_POSIX) |
55 #include <fcntl.h> | 55 #include <fcntl.h> |
56 | 56 |
57 #include "ipc/ipc_channel_posix.h" | 57 #include "ipc/ipc_channel_posix.h" |
58 #elif defined(OS_WIN) | 58 #elif defined(OS_WIN) |
59 #include <windows.h> | 59 #include <windows.h> |
60 | 60 |
61 #include "base/threading/thread.h" | 61 #include "base/threading/thread.h" |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 NaClHandle socket_for_renderer; | 210 NaClHandle socket_for_renderer; |
211 NaClHandle socket_for_sel_ldr; | 211 NaClHandle socket_for_sel_ldr; |
212 | 212 |
213 NaClInternal() | 213 NaClInternal() |
214 : socket_for_renderer(NACL_INVALID_HANDLE), | 214 : socket_for_renderer(NACL_INVALID_HANDLE), |
215 socket_for_sel_ldr(NACL_INVALID_HANDLE) { } | 215 socket_for_sel_ldr(NACL_INVALID_HANDLE) { } |
216 }; | 216 }; |
217 | 217 |
218 // ----------------------------------------------------------------------------- | 218 // ----------------------------------------------------------------------------- |
219 | 219 |
220 NaClProcessHost::PluginListener::PluginListener(NaClProcessHost* host) | |
221 : host_(host) { | |
222 } | |
223 | |
224 bool NaClProcessHost::PluginListener::OnMessageReceived( | |
225 const IPC::Message& msg) { | |
226 return host_->OnUntrustedMessageForwarded(msg); | |
227 } | |
228 | |
229 NaClProcessHost::NaClProcessHost(const GURL& manifest_url, | 220 NaClProcessHost::NaClProcessHost(const GURL& manifest_url, |
230 int render_view_id, | 221 int render_view_id, |
231 uint32 permission_bits, | 222 uint32 permission_bits, |
232 bool uses_irt, | 223 bool uses_irt, |
233 bool enable_dyncode_syscalls, | 224 bool enable_dyncode_syscalls, |
234 bool enable_exception_handling, | 225 bool enable_exception_handling, |
235 bool enable_crash_throttling, | 226 bool enable_crash_throttling, |
236 bool off_the_record, | 227 bool off_the_record, |
237 const base::FilePath& profile_directory) | 228 const base::FilePath& profile_directory) |
238 : manifest_url_(manifest_url), | 229 : manifest_url_(manifest_url), |
239 permissions_(GetNaClPermissions(permission_bits)), | 230 permissions_(GetNaClPermissions(permission_bits)), |
240 #if defined(OS_WIN) | 231 #if defined(OS_WIN) |
241 process_launched_by_broker_(false), | 232 process_launched_by_broker_(false), |
242 #endif | 233 #endif |
243 reply_msg_(NULL), | 234 reply_msg_(NULL), |
244 #if defined(OS_WIN) | 235 #if defined(OS_WIN) |
245 debug_exception_handler_requested_(false), | 236 debug_exception_handler_requested_(false), |
246 #endif | 237 #endif |
247 internal_(new NaClInternal()), | 238 internal_(new NaClInternal()), |
248 weak_factory_(this), | 239 weak_factory_(this), |
249 uses_irt_(uses_irt), | 240 uses_irt_(uses_irt), |
250 enable_debug_stub_(false), | 241 enable_debug_stub_(false), |
251 enable_dyncode_syscalls_(enable_dyncode_syscalls), | 242 enable_dyncode_syscalls_(enable_dyncode_syscalls), |
252 enable_exception_handling_(enable_exception_handling), | 243 enable_exception_handling_(enable_exception_handling), |
253 enable_crash_throttling_(enable_crash_throttling), | 244 enable_crash_throttling_(enable_crash_throttling), |
254 off_the_record_(off_the_record), | 245 off_the_record_(off_the_record), |
255 profile_directory_(profile_directory), | 246 profile_directory_(profile_directory), |
256 ipc_plugin_listener_(this), | |
257 render_view_id_(render_view_id) { | 247 render_view_id_(render_view_id) { |
258 process_.reset(content::BrowserChildProcessHost::Create( | 248 process_.reset(content::BrowserChildProcessHost::Create( |
259 PROCESS_TYPE_NACL_LOADER, this)); | 249 PROCESS_TYPE_NACL_LOADER, this)); |
260 | 250 |
261 // Set the display name so the user knows what plugin the process is running. | 251 // Set the display name so the user knows what plugin the process is running. |
262 // We aren't on the UI thread so getting the pref locale for language | 252 // We aren't on the UI thread so getting the pref locale for language |
263 // formatting isn't possible, so IDN will be lost, but this is probably OK | 253 // formatting isn't possible, so IDN will be lost, but this is probably OK |
264 // for this use case. | 254 // for this use case. |
265 process_->SetName(net::FormatUrl(manifest_url_, std::string())); | 255 process_->SetName(net::FormatUrl(manifest_url_, std::string())); |
266 | 256 |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, | 554 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, |
565 OnQueryKnownToValidate) | 555 OnQueryKnownToValidate) |
566 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, | 556 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, |
567 OnSetKnownToValidate) | 557 OnSetKnownToValidate) |
568 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_ResolveFileToken, | 558 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_ResolveFileToken, |
569 OnResolveFileToken) | 559 OnResolveFileToken) |
570 #if defined(OS_WIN) | 560 #if defined(OS_WIN) |
571 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler, | 561 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler, |
572 OnAttachDebugExceptionHandler) | 562 OnAttachDebugExceptionHandler) |
573 #endif | 563 #endif |
574 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelCreated, | 564 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated, |
575 OnPpapiBrowserChannelCreated) | 565 OnPpapiChannelsCreated) |
576 IPC_MESSAGE_UNHANDLED(handled = false) | 566 IPC_MESSAGE_UNHANDLED(handled = false) |
577 IPC_END_MESSAGE_MAP() | 567 IPC_END_MESSAGE_MAP() |
578 return handled; | 568 return handled; |
579 } | 569 } |
580 | 570 |
581 void NaClProcessHost::OnProcessLaunched() { | 571 void NaClProcessHost::OnProcessLaunched() { |
582 if (!StartWithLaunchedProcess()) | 572 if (!StartWithLaunchedProcess()) |
583 delete this; | 573 delete this; |
584 } | 574 } |
585 | 575 |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 bool NaClProcessHost::SendStart() { | 769 bool NaClProcessHost::SendStart() { |
780 if (!enable_ppapi_proxy()) { | 770 if (!enable_ppapi_proxy()) { |
781 if (!ReplyToRenderer(IPC::ChannelHandle())) | 771 if (!ReplyToRenderer(IPC::ChannelHandle())) |
782 return false; | 772 return false; |
783 } | 773 } |
784 return StartNaClExecution(); | 774 return StartNaClExecution(); |
785 } | 775 } |
786 | 776 |
787 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is | 777 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is |
788 // received. | 778 // received. |
789 void NaClProcessHost::OnPpapiBrowserChannelCreated( | 779 void NaClProcessHost::OnPpapiChannelsCreated( |
790 const IPC::ChannelHandle& channel_handle) { | 780 const IPC::ChannelHandle& browser_channel_handle, |
| 781 const IPC::ChannelHandle& renderer_channel_handle) { |
791 // Only renderer processes should create a channel. | 782 // Only renderer processes should create a channel. |
792 DCHECK(enable_ppapi_proxy()); | 783 DCHECK(enable_ppapi_proxy()); |
793 if (!ipc_proxy_channel_.get()) { | 784 if (!ipc_proxy_channel_.get()) { |
794 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type); | 785 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type); |
795 | 786 |
796 ipc_proxy_channel_.reset( | 787 ipc_proxy_channel_.reset( |
797 new IPC::ChannelProxy(channel_handle, | 788 new IPC::ChannelProxy(browser_channel_handle, |
798 IPC::Channel::MODE_CLIENT, | 789 IPC::Channel::MODE_CLIENT, |
799 &ipc_plugin_listener_, | 790 NULL, |
800 base::MessageLoopProxy::current().get())); | 791 base::MessageLoopProxy::current().get())); |
801 // Create the browser ppapi host and enable PPAPI message dispatching to the | 792 // Create the browser ppapi host and enable PPAPI message dispatching to the |
802 // browser process. | 793 // browser process. |
803 ppapi_host_.reset(content::BrowserPpapiHost::CreateExternalPluginProcess( | 794 ppapi_host_.reset(content::BrowserPpapiHost::CreateExternalPluginProcess( |
804 ipc_proxy_channel_.get(), // sender | 795 ipc_proxy_channel_.get(), // sender |
805 permissions_, | 796 permissions_, |
806 process_->GetData().handle, | 797 process_->GetData().handle, |
807 ipc_proxy_channel_.get(), | 798 ipc_proxy_channel_.get(), |
808 nacl_host_message_filter_->render_process_id(), | 799 nacl_host_message_filter_->render_process_id(), |
809 render_view_id_, | 800 render_view_id_, |
810 profile_directory_)); | 801 profile_directory_)); |
811 ppapi_host_->SetOnKeepaliveCallback( | 802 ppapi_host_->SetOnKeepaliveCallback( |
812 NaClBrowser::GetDelegate()->GetOnKeepaliveCallback()); | 803 NaClBrowser::GetDelegate()->GetOnKeepaliveCallback()); |
813 | 804 |
814 ppapi::PpapiNaClChannelArgs args; | 805 ppapi::PpapiNaClPluginArgs args; |
815 args.off_the_record = nacl_host_message_filter_->off_the_record(); | 806 args.off_the_record = nacl_host_message_filter_->off_the_record(); |
816 args.permissions = permissions_; | 807 args.permissions = permissions_; |
817 CommandLine* cmdline = CommandLine::ForCurrentProcess(); | 808 CommandLine* cmdline = CommandLine::ForCurrentProcess(); |
818 DCHECK(cmdline); | 809 DCHECK(cmdline); |
819 std::string flag_whitelist[] = { | 810 std::string flag_whitelist[] = { |
820 switches::kPpapiKeepAliveThrottle, | 811 switches::kPpapiKeepAliveThrottle, |
821 switches::kV, | 812 switches::kV, |
822 switches::kVModule, | 813 switches::kVModule, |
823 }; | 814 }; |
824 for (size_t i = 0; i < arraysize(flag_whitelist); ++i) { | 815 for (size_t i = 0; i < arraysize(flag_whitelist); ++i) { |
825 std::string value = cmdline->GetSwitchValueASCII(flag_whitelist[i]); | 816 std::string value = cmdline->GetSwitchValueASCII(flag_whitelist[i]); |
826 if (!value.empty()) { | 817 if (!value.empty()) { |
827 args.switch_names.push_back(flag_whitelist[i]); | 818 args.switch_names.push_back(flag_whitelist[i]); |
828 args.switch_values.push_back(value); | 819 args.switch_values.push_back(value); |
829 } | 820 } |
830 } | 821 } |
831 | 822 |
832 ppapi_host_->GetPpapiHost()->AddHostFactoryFilter( | 823 ppapi_host_->GetPpapiHost()->AddHostFactoryFilter( |
833 scoped_ptr<ppapi::host::HostFactory>( | 824 scoped_ptr<ppapi::host::HostFactory>( |
834 NaClBrowser::GetDelegate()->CreatePpapiHostFactory( | 825 NaClBrowser::GetDelegate()->CreatePpapiHostFactory( |
835 ppapi_host_.get()))); | 826 ppapi_host_.get()))); |
836 | 827 |
837 // Send a message to create the NaCl-Renderer channel. The handle is just | 828 // Send a message to initialize the IPC dispatchers in the NaCl plugin. |
838 // a place holder. | 829 ipc_proxy_channel_->Send(new PpapiMsg_InitializeNaClDispatcher(args)); |
839 ipc_proxy_channel_->Send( | 830 |
840 new PpapiMsg_CreateNaClChannel( | 831 // Let the renderer know that the IPC channels are established. |
841 args, | 832 ReplyToRenderer(renderer_channel_handle); |
842 SerializedHandle(SerializedHandle::CHANNEL_HANDLE, | |
843 IPC::InvalidPlatformFileForTransit()))); | |
844 } else { | 833 } else { |
845 // Attempt to open more than 1 browser channel is not supported. | 834 // Attempt to open more than 1 browser channel is not supported. |
846 // Shut down the NaCl process. | 835 // Shut down the NaCl process. |
847 process_->GetHost()->ForceShutdown(); | 836 process_->GetHost()->ForceShutdown(); |
848 } | 837 } |
849 } | 838 } |
850 | 839 |
851 void NaClProcessHost::OnPpapiRendererChannelCreated( | |
852 const IPC::ChannelHandle& channel_handle) { | |
853 if (reply_msg_) { | |
854 ReplyToRenderer(channel_handle); | |
855 } else { | |
856 // Attempt to open more than 1 NaCl renderer channel is not supported. | |
857 // Shut down the NaCl process. | |
858 process_->GetHost()->ForceShutdown(); | |
859 } | |
860 } | |
861 | |
862 bool NaClProcessHost::OnUntrustedMessageForwarded(const IPC::Message& msg) { | |
863 // Handle messages that have been forwarded from our PluginListener. | |
864 // These messages come from untrusted code so should be handled with care. | |
865 bool handled = true; | |
866 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) | |
867 IPC_MESSAGE_HANDLER(PpapiHostMsg_NaClChannelCreated, | |
868 OnPpapiRendererChannelCreated) | |
869 IPC_MESSAGE_UNHANDLED(handled = false) | |
870 IPC_END_MESSAGE_MAP() | |
871 return handled; | |
872 } | |
873 | |
874 bool NaClProcessHost::StartWithLaunchedProcess() { | 840 bool NaClProcessHost::StartWithLaunchedProcess() { |
875 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 841 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
876 | 842 |
877 if (nacl_browser->IsReady()) { | 843 if (nacl_browser->IsReady()) { |
878 return SendStart(); | 844 return SendStart(); |
879 } else if (nacl_browser->IsOk()) { | 845 } else if (nacl_browser->IsOk()) { |
880 nacl_browser->WaitForResources( | 846 nacl_browser->WaitForResources( |
881 base::Bind(&NaClProcessHost::OnResourcesReady, | 847 base::Bind(&NaClProcessHost::OnResourcesReady, |
882 weak_factory_.GetWeakPtr())); | 848 weak_factory_.GetWeakPtr())); |
883 return true; | 849 return true; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1038 process_handle.Take(), info, | 1004 process_handle.Take(), info, |
1039 base::MessageLoopProxy::current(), | 1005 base::MessageLoopProxy::current(), |
1040 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, | 1006 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, |
1041 weak_factory_.GetWeakPtr())); | 1007 weak_factory_.GetWeakPtr())); |
1042 return true; | 1008 return true; |
1043 } | 1009 } |
1044 } | 1010 } |
1045 #endif | 1011 #endif |
1046 | 1012 |
1047 } // namespace nacl | 1013 } // namespace nacl |
OLD | NEW |