Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(506)

Side by Side Diff: components/nacl/renderer/ppb_nacl_private_impl.cc

Issue 131413009: Prototype: Use Chromium IPC for plugin LOAD_MODULE. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased, some FIXMEs cleaned up Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/renderer/ppb_nacl_private_impl.h" 5 #include "components/nacl/renderer/ppb_nacl_private_impl.h"
6 6
7 #ifndef DISABLE_NACL 7 #ifndef DISABLE_NACL
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/rand_util.h" 12 #include "base/rand_util.h"
13 #include "components/nacl/common/nacl_host_messages.h" 13 #include "components/nacl/common/nacl_host_messages.h"
14 #include "components/nacl/common/nacl_messages.h"
14 #include "components/nacl/common/nacl_types.h" 15 #include "components/nacl/common/nacl_types.h"
15 #include "components/nacl/renderer/pnacl_translation_resource_host.h" 16 #include "components/nacl/renderer/pnacl_translation_resource_host.h"
17 #include "components/nacl/renderer/trusted_plugin_channel.h"
16 #include "content/public/common/content_client.h" 18 #include "content/public/common/content_client.h"
17 #include "content/public/common/content_switches.h" 19 #include "content/public/common/content_switches.h"
18 #include "content/public/common/sandbox_init.h" 20 #include "content/public/common/sandbox_init.h"
19 #include "content/public/renderer/pepper_plugin_instance.h" 21 #include "content/public/renderer/pepper_plugin_instance.h"
20 #include "content/public/renderer/render_thread.h" 22 #include "content/public/renderer/render_thread.h"
21 #include "content/public/renderer/render_view.h" 23 #include "content/public/renderer/render_view.h"
22 #include "content/public/renderer/renderer_ppapi_host.h" 24 #include "content/public/renderer/renderer_ppapi_host.h"
23 #include "ppapi/c/pp_bool.h" 25 #include "ppapi/c/pp_bool.h"
24 #include "ppapi/c/private/pp_file_handle.h" 26 #include "ppapi/c/private/pp_file_handle.h"
25 #include "ppapi/native_client/src/trusted/plugin/nacl_entry_points.h" 27 #include "ppapi/native_client/src/trusted/plugin/nacl_entry_points.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 base::ProcessId plugin_pid; 62 base::ProcessId plugin_pid;
61 int plugin_child_id; 63 int plugin_child_id;
62 IPC::ChannelHandle channel_handle; 64 IPC::ChannelHandle channel_handle;
63 }; 65 };
64 66
65 typedef std::map<PP_Instance, InstanceInfo> InstanceInfoMap; 67 typedef std::map<PP_Instance, InstanceInfo> InstanceInfoMap;
66 68
67 base::LazyInstance<InstanceInfoMap> g_instance_info = 69 base::LazyInstance<InstanceInfoMap> g_instance_info =
68 LAZY_INSTANCE_INITIALIZER; 70 LAZY_INSTANCE_INITIALIZER;
69 71
72 typedef std::map<PP_Instance, nacl::TrustedPluginChannel*>
73 InstanceTrustedChannelMap;
74
75 base::LazyInstance<InstanceTrustedChannelMap> g_channel_map =
76 LAZY_INSTANCE_INITIALIZER;
77
70 static int GetRoutingID(PP_Instance instance) { 78 static int GetRoutingID(PP_Instance instance) {
71 // Check that we are on the main renderer thread. 79 // Check that we are on the main renderer thread.
72 DCHECK(content::RenderThread::Get()); 80 DCHECK(content::RenderThread::Get());
73 content::RendererPpapiHost *host = 81 content::RendererPpapiHost *host =
74 content::RendererPpapiHost::GetForPPInstance(instance); 82 content::RendererPpapiHost::GetForPPInstance(instance);
75 if (!host) 83 if (!host)
76 return 0; 84 return 0;
77 return host->GetRoutingIDForWidget(instance); 85 return host->GetRoutingIDForWidget(instance);
78 } 86 }
79 87
80 // Launch NaCl's sel_ldr process. 88 // Launch NaCl's sel_ldr process.
81 PP_ExternalPluginResult LaunchSelLdr(PP_Instance instance, 89 void LaunchSelLdr(PP_Instance instance,
82 const char* alleged_url, 90 const char* alleged_url,
83 PP_Bool uses_irt, 91 PP_Bool uses_irt,
84 PP_Bool uses_ppapi, 92 PP_Bool uses_ppapi,
85 PP_Bool enable_ppapi_dev, 93 PP_Bool enable_ppapi_dev,
86 PP_Bool enable_dyncode_syscalls, 94 PP_Bool enable_dyncode_syscalls,
87 PP_Bool enable_exception_handling, 95 PP_Bool enable_exception_handling,
88 PP_Bool enable_crash_throttling, 96 PP_Bool enable_crash_throttling,
89 void* imc_handle, 97 void* imc_handle,
90 struct PP_Var* error_message) { 98 struct PP_Var* error_message,
99 PP_CompletionCallback callback) {
91 nacl::FileDescriptor result_socket; 100 nacl::FileDescriptor result_socket;
92 IPC::Sender* sender = content::RenderThread::Get(); 101 IPC::Sender* sender = content::RenderThread::Get();
93 DCHECK(sender); 102 DCHECK(sender);
94 *error_message = PP_MakeUndefined(); 103 *error_message = PP_MakeUndefined();
95 int routing_id = 0; 104 int routing_id = 0;
96 // If the nexe uses ppapi APIs, we need a routing ID. 105 // If the nexe uses ppapi APIs, we need a routing ID.
97 // To get the routing ID, we must be on the main thread. 106 // To get the routing ID, we must be on the main thread.
98 // Some nexes do not use ppapi and launch from the background thread, 107 // Some nexes do not use ppapi and launch from the background thread,
99 // so those nexes can skip finding a routing_id. 108 // so those nexes can skip finding a routing_id.
100 if (uses_ppapi) { 109 if (uses_ppapi) {
101 routing_id = GetRoutingID(instance); 110 routing_id = GetRoutingID(instance);
102 if (!routing_id) 111 if (!routing_id) {
103 return PP_EXTERNAL_PLUGIN_FAILED; 112 PP_RunCompletionCallback(&callback, PP_ERROR_FAILED);
113 return;
114 }
104 } 115 }
105 116
106 InstanceInfo instance_info; 117 InstanceInfo instance_info;
107 instance_info.url = GURL(alleged_url); 118 instance_info.url = GURL(alleged_url);
108 119
109 uint32_t perm_bits = ppapi::PERMISSION_NONE; 120 uint32_t perm_bits = ppapi::PERMISSION_NONE;
110 // Conditionally block 'Dev' interfaces. We do this for the NaCl process, so 121 // Conditionally block 'Dev' interfaces. We do this for the NaCl process, so
111 // it's clearer to developers when they are using 'Dev' inappropriately. We 122 // it's clearer to developers when they are using 'Dev' inappropriately. We
112 // must also check on the trusted side of the proxy. 123 // must also check on the trusted side of the proxy.
113 if (enable_ppapi_dev) 124 if (enable_ppapi_dev)
114 perm_bits |= ppapi::PERMISSION_DEV; 125 perm_bits |= ppapi::PERMISSION_DEV;
115 instance_info.permissions = 126 instance_info.permissions =
116 ppapi::PpapiPermissions::GetForCommandLine(perm_bits); 127 ppapi::PpapiPermissions::GetForCommandLine(perm_bits);
117 std::string error_message_string; 128 std::string error_message_string;
118 nacl::NaClLaunchResult launch_result; 129 nacl::NaClLaunchResult launch_result;
119 130
120 if (!sender->Send(new NaClHostMsg_LaunchNaCl( 131 if (!sender->Send(new NaClHostMsg_LaunchNaCl(
121 nacl::NaClLaunchParams(instance_info.url.spec(), 132 nacl::NaClLaunchParams(instance_info.url.spec(),
122 routing_id, 133 routing_id,
123 perm_bits, 134 perm_bits,
124 PP_ToBool(uses_irt), 135 PP_ToBool(uses_irt),
125 PP_ToBool(enable_dyncode_syscalls), 136 PP_ToBool(enable_dyncode_syscalls),
126 PP_ToBool(enable_exception_handling), 137 PP_ToBool(enable_exception_handling),
127 PP_ToBool(enable_crash_throttling)), 138 PP_ToBool(enable_crash_throttling)),
128 &launch_result, 139 &launch_result,
129 &error_message_string))) { 140 &error_message_string))) {
130 return PP_EXTERNAL_PLUGIN_FAILED; 141 PP_RunCompletionCallback(&callback, PP_ERROR_FAILED);
142 return;
131 } 143 }
132 if (!error_message_string.empty()) { 144 if (!error_message_string.empty()) {
133 *error_message = ppapi::StringVar::StringToPPVar(error_message_string); 145 *error_message = ppapi::StringVar::StringToPPVar(error_message_string);
134 return PP_EXTERNAL_PLUGIN_FAILED; 146 PP_RunCompletionCallback(&callback, PP_ERROR_FAILED);
147 return;
135 } 148 }
136 result_socket = launch_result.imc_channel_handle; 149 result_socket = launch_result.imc_channel_handle;
137 instance_info.channel_handle = launch_result.ipc_channel_handle; 150 instance_info.channel_handle = launch_result.untrusted_ipc_channel_handle;
138 instance_info.plugin_pid = launch_result.plugin_pid; 151 instance_info.plugin_pid = launch_result.plugin_pid;
139 instance_info.plugin_child_id = launch_result.plugin_child_id; 152 instance_info.plugin_child_id = launch_result.plugin_child_id;
140 // Don't save instance_info if channel handle is invalid. 153 // Don't save instance_info if channel handle is invalid.
141 bool invalid_handle = instance_info.channel_handle.name.empty(); 154 bool invalid_handle = instance_info.channel_handle.name.empty();
142 #if defined(OS_POSIX) 155 #if defined(OS_POSIX)
143 if (!invalid_handle) 156 if (!invalid_handle)
144 invalid_handle = (instance_info.channel_handle.socket.fd == -1); 157 invalid_handle = (instance_info.channel_handle.socket.fd == -1);
145 #endif 158 #endif
146 if (!invalid_handle) 159 if (!invalid_handle)
147 g_instance_info.Get()[instance] = instance_info; 160 g_instance_info.Get()[instance] = instance_info;
148 161
149 *(static_cast<NaClHandle*>(imc_handle)) = 162 // Stash the trusted handle as well.
150 nacl::ToNativeHandle(result_socket); 163 invalid_handle = launch_result.trusted_ipc_channel_handle.name.empty();
164 #if defined(OS_POSIX)
165 if (!invalid_handle)
166 invalid_handle = (launch_result.trusted_ipc_channel_handle.socket.fd == -1);
167 #endif
151 168
152 return PP_EXTERNAL_PLUGIN_OK; 169 if (!invalid_handle) {
170 g_channel_map.Get()[instance] = new nacl::TrustedPluginChannel(
171 launch_result.trusted_ipc_channel_handle, callback);
172 *(static_cast<NaClHandle*>(imc_handle)) =
173 nacl::ToNativeHandle(result_socket);
174 } else {
175 PP_RunCompletionCallback(&callback, PP_ERROR_FAILED);
176 }
153 } 177 }
154 178
155 PP_ExternalPluginResult StartPpapiProxy(PP_Instance instance) { 179 PP_ExternalPluginResult StartPpapiProxy(PP_Instance instance) {
156 InstanceInfoMap& map = g_instance_info.Get(); 180 InstanceInfoMap& map = g_instance_info.Get();
157 InstanceInfoMap::iterator it = map.find(instance); 181 InstanceInfoMap::iterator it = map.find(instance);
158 if (it == map.end()) { 182 if (it == map.end()) {
159 DLOG(ERROR) << "Could not find instance ID"; 183 DLOG(ERROR) << "Could not find instance ID";
160 return PP_EXTERNAL_PLUGIN_FAILED; 184 return PP_EXTERNAL_PLUGIN_FAILED;
161 } 185 }
162 InstanceInfo instance_info = it->second; 186 InstanceInfo instance_info = it->second;
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 } 426 }
403 427
404 void SetReadOnlyProperty(PP_Instance instance, 428 void SetReadOnlyProperty(PP_Instance instance,
405 struct PP_Var key, 429 struct PP_Var key,
406 struct PP_Var value) { 430 struct PP_Var value) {
407 content::PepperPluginInstance* plugin_instance = 431 content::PepperPluginInstance* plugin_instance =
408 content::PepperPluginInstance::Get(instance); 432 content::PepperPluginInstance::Get(instance);
409 plugin_instance->SetEmbedProperty(key, value); 433 plugin_instance->SetEmbedProperty(key, value);
410 } 434 }
411 435
436 PP_Bool LoadModule(PP_Instance instance, PP_FileHandle handle,
437 uint32_t *nacl_error_code) {
438 fprintf(stderr, "PPB_NaCl_Private LoadModule()\n");
439 // We can't use PepperPluginInstance here because it doesn't have sufficient
440 // DEPS to see the NaClProcessMsg_LoadModule message. Therefore, we must do
441 // our own accounting and keep a channel map here.
442
443 InstanceTrustedChannelMap::iterator it = g_channel_map.Get().find(instance);
444 if (it == g_channel_map.Get().end()) {
445 NOTREACHED();
446 return PP_FALSE;
447 }
448 nacl::TrustedPluginChannel* channel = it->second;
449 IPC::PlatformFileForTransit platform_file_for_transit;
450 #if defined(OS_WIN)
451 platform_file_for_transit = handle;
452 #elif defined(OS_POSIX)
453 platform_file_for_transit = base::FileDescriptor(handle, false);
454 #endif
455 fprintf(stderr, "sending NaClProcessMsg_LoadModule\n");
456 NaClErrorCode code;
457 bool ok = channel->Send(
458 new NaClProcessMsg_LoadModule(platform_file_for_transit,
459 &code));
460 *nacl_error_code = code;
461 fprintf(stderr, "sent NaClProcessMsg_LoadModule\n");
462 return PP_FromBool(ok);
463 }
464
465 PP_Bool StartModule(PP_Instance instance) {
466 InstanceTrustedChannelMap::iterator it = g_channel_map.Get().find(instance);
467 if (it == g_channel_map.Get().end()) {
468 NOTREACHED();
469 return PP_FALSE;
470 }
471 nacl::TrustedPluginChannel* channel = it->second;
472 fprintf(stderr, "sending NaClProcessMsg_StartModule\n");
473 bool ok = channel->Send(new NaClProcessMsg_StartModule());
474 fprintf(stderr, "sent NaClProcessMsg_StartModule\n");
475 return PP_FromBool(ok);
476 }
477
412 const PPB_NaCl_Private nacl_interface = { 478 const PPB_NaCl_Private nacl_interface = {
413 &LaunchSelLdr, 479 &LaunchSelLdr,
414 &StartPpapiProxy, 480 &StartPpapiProxy,
415 &UrandomFD, 481 &UrandomFD,
416 &Are3DInterfacesDisabled, 482 &Are3DInterfacesDisabled,
417 &BrokerDuplicateHandle, 483 &BrokerDuplicateHandle,
418 &GetReadonlyPnaclFD, 484 &GetReadonlyPnaclFD,
419 &CreateTemporaryFile, 485 &CreateTemporaryFile,
420 &GetNexeFd, 486 &GetNexeFd,
421 &ReportTranslationFinished, 487 &ReportTranslationFinished,
422 &ReportNaClError, 488 &ReportNaClError,
423 &OpenNaClExecutable, 489 &OpenNaClExecutable,
424 &DispatchEvent, 490 &DispatchEvent,
425 &SetReadOnlyProperty 491 &SetReadOnlyProperty,
492 &LoadModule,
493 &StartModule
426 }; 494 };
427 495
428 } // namespace 496 } // namespace
429 497
430 namespace nacl { 498 namespace nacl {
431 499
432 const PPB_NaCl_Private* GetNaClPrivateInterface() { 500 const PPB_NaCl_Private* GetNaClPrivateInterface() {
433 return &nacl_interface; 501 return &nacl_interface;
434 } 502 }
435 503
436 } // namespace nacl 504 } // namespace nacl
437 505
438 #endif // DISABLE_NACL 506 #endif // DISABLE_NACL
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698