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

Side by Side Diff: chrome/renderer/pepper/ppb_nacl_private_impl.cc

Issue 11140046: Add a content API to connect a Native Client module to an out-of-process PPAPI proxy. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 2 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
« no previous file with comments | « no previous file | content/public/renderer/renderer_ppapi_host.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "chrome/renderer/pepper/ppb_nacl_private_impl.h" 5 #include "chrome/renderer/pepper/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/message_loop.h"
13 #include "base/rand_util.h" 12 #include "base/rand_util.h"
14 #include "chrome/common/chrome_switches.h" 13 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/render_messages.h" 14 #include "chrome/common/render_messages.h"
16 #include "chrome/renderer/chrome_render_process_observer.h" 15 #include "chrome/renderer/chrome_render_process_observer.h"
17 #include "content/public/common/content_client.h" 16 #include "content/public/common/content_client.h"
18 #include "content/public/common/content_switches.h" 17 #include "content/public/common/content_switches.h"
19 #include "content/public/common/sandbox_init.h" 18 #include "content/public/common/sandbox_init.h"
19 #include "content/public/renderer/renderer_ppapi_host.h"
20 #include "content/public/renderer/render_thread.h" 20 #include "content/public/renderer/render_thread.h"
21 #include "content/public/renderer/render_view.h"
22 #include "content/public/renderer/renderer_restrict_dispatch_group.h"
23 #include "ipc/ipc_sync_message_filter.h" 21 #include "ipc/ipc_sync_message_filter.h"
24 #include "ppapi/c/pp_bool.h" 22 #include "ppapi/c/pp_bool.h"
25 #include "ppapi/c/private/pp_file_handle.h" 23 #include "ppapi/c/private/pp_file_handle.h"
26 #include "ppapi/c/private/ppb_nacl_private.h" 24 #include "ppapi/c/private/ppb_nacl_private.h"
27 #include "ppapi/native_client/src/trusted/plugin/nacl_entry_points.h" 25 #include "ppapi/native_client/src/trusted/plugin/nacl_entry_points.h"
28 #include "ppapi/proxy/host_dispatcher.h"
29 #include "ppapi/proxy/proxy_channel.h"
30 #include "ppapi/shared_impl/ppapi_preferences.h" 26 #include "ppapi/shared_impl/ppapi_preferences.h"
31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
35 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
36 #include "webkit/plugins/ppapi/host_globals.h" 27 #include "webkit/plugins/ppapi/host_globals.h"
37 #include "webkit/plugins/ppapi/plugin_module.h" 28 #include "webkit/plugins/ppapi/plugin_module.h"
38 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" 29 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
39 30
40 using content::RenderThread;
41 using content::RenderView;
42 using webkit::ppapi::HostGlobals;
43 using webkit::ppapi::PluginInstance;
44 using webkit::ppapi::PluginDelegate;
45 using webkit::ppapi::PluginModule;
46 using WebKit::WebView;
47
48 namespace { 31 namespace {
49 32
50 // This allows us to send requests from background threads. 33 // This allows us to send requests from background threads.
51 // E.g., to do LaunchSelLdr for helper nexes (which is done synchronously), 34 // E.g., to do LaunchSelLdr for helper nexes (which is done synchronously),
52 // in a background thread, to avoid jank. 35 // in a background thread, to avoid jank.
53 base::LazyInstance<scoped_refptr<IPC::SyncMessageFilter> > 36 base::LazyInstance<scoped_refptr<IPC::SyncMessageFilter> >
54 g_background_thread_sender = LAZY_INSTANCE_INITIALIZER; 37 g_background_thread_sender = LAZY_INSTANCE_INITIALIZER;
55 38
56 typedef std::map<PP_Instance, IPC::ChannelHandle> ChannelHandleMap; 39 typedef std::map<PP_Instance, IPC::ChannelHandle> ChannelHandleMap;
57 40
(...skipping 30 matching lines...) Expand all
88 71
89 CHECK(static_cast<int>(sockets.size()) == socket_count); 72 CHECK(static_cast<int>(sockets.size()) == socket_count);
90 for (int i = 0; i < socket_count; i++) { 73 for (int i = 0; i < socket_count; i++) {
91 static_cast<nacl::Handle*>(imc_handles)[i] = 74 static_cast<nacl::Handle*>(imc_handles)[i] =
92 nacl::ToNativeHandle(sockets[i]); 75 nacl::ToNativeHandle(sockets[i]);
93 } 76 }
94 77
95 return PP_TRUE; 78 return PP_TRUE;
96 } 79 }
97 80
98 class ProxyChannelDelegate
99 : public ppapi::proxy::ProxyChannel::Delegate {
100 public:
101 ProxyChannelDelegate();
102 virtual ~ProxyChannelDelegate();
103
104 // ProxyChannel::Delegate implementation.
105 virtual base::MessageLoopProxy* GetIPCMessageLoop() OVERRIDE;
106 virtual base::WaitableEvent* GetShutdownEvent() OVERRIDE;
107 virtual IPC::PlatformFileForTransit ShareHandleWithRemote(
108 base::PlatformFile handle,
109 const IPC::SyncChannel& channel,
110 bool should_close_source) OVERRIDE;
111 private:
112 // TODO(bbudge) Modify the content public API so we can get
113 // the renderer process's shutdown event.
114 base::WaitableEvent shutdown_event_;
115 };
116
117 ProxyChannelDelegate::ProxyChannelDelegate()
118 : shutdown_event_(true, false) {
119 }
120
121 ProxyChannelDelegate::~ProxyChannelDelegate() {
122 }
123
124 base::MessageLoopProxy* ProxyChannelDelegate::GetIPCMessageLoop() {
125 return RenderThread::Get()->GetIOMessageLoopProxy().get();
126 }
127
128 base::WaitableEvent* ProxyChannelDelegate::GetShutdownEvent() {
129 return &shutdown_event_;
130 }
131
132 IPC::PlatformFileForTransit ProxyChannelDelegate::ShareHandleWithRemote(
133 base::PlatformFile handle,
134 const IPC::SyncChannel& channel,
135 bool should_close_source) {
136 return content::BrokerGetFileHandleForProcess(handle, channel.peer_pid(),
137 should_close_source);
138 }
139
140 // Stubbed out SyncMessageStatusReceiver, required by HostDispatcher.
141 // TODO(bbudge) Use a content::PepperHungPluginFilter instead.
142 class SyncMessageStatusReceiver
143 : public ppapi::proxy::HostDispatcher::SyncMessageStatusReceiver {
144 public:
145 SyncMessageStatusReceiver() {}
146
147 // SyncMessageStatusReceiver implementation.
148 virtual void BeginBlockOnSyncMessage() OVERRIDE {}
149 virtual void EndBlockOnSyncMessage() OVERRIDE {}
150
151 private:
152 virtual ~SyncMessageStatusReceiver() {}
153 };
154
155 class OutOfProcessProxy : public PluginDelegate::OutOfProcessProxy {
156 public:
157 OutOfProcessProxy() {}
158 virtual ~OutOfProcessProxy() {}
159
160 bool Init(const IPC::ChannelHandle& channel_handle,
161 PP_Module pp_module,
162 PP_GetInterface_Func local_get_interface,
163 const ppapi::Preferences& preferences,
164 SyncMessageStatusReceiver* status_receiver,
165 const ppapi::PpapiPermissions& permissions) {
166 dispatcher_delegate_.reset(new ProxyChannelDelegate);
167 dispatcher_.reset(new ppapi::proxy::HostDispatcher(
168 pp_module, local_get_interface, status_receiver, permissions));
169
170 if (!dispatcher_->InitHostWithChannel(dispatcher_delegate_.get(),
171 channel_handle,
172 true, // Client.
173 preferences)) {
174 dispatcher_.reset();
175 dispatcher_delegate_.reset();
176 return false;
177 }
178
179 // Make sure that incoming plugin->renderer "unblock" messages can ONLY
180 // unblock other pepper messages.
181 dispatcher_->channel()->SetRestrictDispatchChannelGroup(
182 content::kRendererRestrictDispatchGroup_Pepper);
183 return true;
184 }
185
186 // OutOfProcessProxy implementation.
187 virtual const void* GetProxiedInterface(const char* name) OVERRIDE {
188 return dispatcher_->GetProxiedInterface(name);
189 }
190 virtual void AddInstance(PP_Instance instance) OVERRIDE {
191 ppapi::proxy::HostDispatcher::SetForInstance(instance, dispatcher_.get());
192 }
193 virtual void RemoveInstance(PP_Instance instance) OVERRIDE {
194 ppapi::proxy::HostDispatcher::RemoveForInstance(instance);
195 }
196
197 private:
198 scoped_ptr<ppapi::proxy::HostDispatcher> dispatcher_;
199 scoped_ptr<ppapi::proxy::ProxyChannel::Delegate> dispatcher_delegate_;
200 };
201
202 PP_Bool StartPpapiProxy(PP_Instance instance) { 81 PP_Bool StartPpapiProxy(PP_Instance instance) {
203 if (CommandLine::ForCurrentProcess()->HasSwitch( 82 if (CommandLine::ForCurrentProcess()->HasSwitch(
204 switches::kEnableNaClIPCProxy)) { 83 switches::kEnableNaClIPCProxy)) {
205 ChannelHandleMap& map = g_channel_handle_map.Get(); 84 ChannelHandleMap& map = g_channel_handle_map.Get();
206 ChannelHandleMap::iterator it = map.find(instance); 85 ChannelHandleMap::iterator it = map.find(instance);
207 if (it == map.end()) 86 if (it == map.end())
208 return PP_FALSE; 87 return PP_FALSE;
209 IPC::ChannelHandle channel_handle = it->second; 88 IPC::ChannelHandle channel_handle = it->second;
210 map.erase(it); 89 map.erase(it);
211 90
212 PluginInstance* plugin_instance = 91 webkit::ppapi::PluginInstance* plugin_instance =
213 content::GetHostGlobals()->GetInstance(instance); 92 content::GetHostGlobals()->GetInstance(instance);
214 if (!plugin_instance) 93 if (!plugin_instance)
215 return PP_FALSE; 94 return PP_FALSE;
216 95
217 WebView* web_view = 96 // Create a new module for each instance of the NaCl plugin that is using
218 plugin_instance->container()->element().document().frame()->view(); 97 // the IPC based out-of-process proxy. We can't use the existing module,
219 RenderView* render_view = content::RenderView::FromWebView(web_view); 98 // because it is configured for the in-process NaCl plugin, and we must
220 99 // keep it that way to allow the page to create other instances.
221 PluginModule* plugin_module = plugin_instance->module(); 100 webkit::ppapi::PluginModule* plugin_module = plugin_instance->module();
222 101 scoped_refptr<webkit::ppapi::PluginModule> nacl_plugin_module(
223 scoped_refptr<SyncMessageStatusReceiver> 102 plugin_module->CreateModuleForNaClInstance());
224 status_receiver(new SyncMessageStatusReceiver());
225 scoped_ptr<OutOfProcessProxy> out_of_process_proxy(new OutOfProcessProxy);
226 // Create a new module for each instance of the NaCl plugin that is using
227 // the IPC based out-of-process proxy. We can't use the existing module,
228 // because it is configured for the in-process NaCl plugin, and we must
229 // keep it that way to allow the page to create other instances.
230 scoped_refptr<PluginModule> nacl_plugin_module(
231 plugin_module->CreateModuleForNaClInstance());
232 103
233 // TODO(brettw) bug 153036 set NaCl permissions to allow dev interface 104 // TODO(brettw) bug 153036 set NaCl permissions to allow dev interface
234 // usage when necessary. 105 // usage when necessary.
235 ppapi::PpapiPermissions permissions; 106 ppapi::PpapiPermissions permissions;
236 107 // TODO(bbudge) fill in place-holder params below with the nexe URL and
237 if (out_of_process_proxy->Init( 108 // NaCl process id.
109 content::RendererPpapiHost* renderer_ppapi_host =
110 content::RendererPpapiHost::CreateExternalPluginModule(
111 nacl_plugin_module,
112 plugin_instance,
113 FilePath(FILE_PATH_LITERAL("NaCl")),
114 permissions,
238 channel_handle, 115 channel_handle,
239 nacl_plugin_module->pp_module(), 116 0); // plugin_child_id
240 PluginModule::GetLocalGetInterfaceFunc(), 117 if (renderer_ppapi_host) {
241 ppapi::Preferences(render_view->GetWebkitPreferences()), 118 // Allow the module to reset the instance to the new proxy.
242 status_receiver.get(), 119 nacl_plugin_module->InitAsProxiedNaCl(plugin_instance);
243 permissions)) {
244 nacl_plugin_module->InitAsProxiedNaCl(
245 out_of_process_proxy.PassAs<PluginDelegate::OutOfProcessProxy>(),
246 instance);
247 return PP_TRUE; 120 return PP_TRUE;
248 } 121 }
249 } 122 }
250
251 return PP_FALSE; 123 return PP_FALSE;
252 } 124 }
253 125
254 int UrandomFD(void) { 126 int UrandomFD(void) {
255 #if defined(OS_POSIX) 127 #if defined(OS_POSIX)
256 return base::GetUrandomFD(); 128 return base::GetUrandomFD();
257 #else 129 #else
258 return -1; 130 return -1;
259 #endif 131 #endif
260 } 132 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 &IsPnaclEnabled 217 &IsPnaclEnabled
346 }; 218 };
347 219
348 } // namespace 220 } // namespace
349 221
350 const PPB_NaCl_Private* PPB_NaCl_Private_Impl::GetInterface() { 222 const PPB_NaCl_Private* PPB_NaCl_Private_Impl::GetInterface() {
351 return &nacl_interface; 223 return &nacl_interface;
352 } 224 }
353 225
354 #endif // DISABLE_NACL 226 #endif // DISABLE_NACL
OLDNEW
« no previous file with comments | « no previous file | content/public/renderer/renderer_ppapi_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698