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

Side by Side Diff: content/child/npobject_proxy.cc

Issue 19462016: Move npapi related files from content\child to the new content\child\npapi directory. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years, 5 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 | « content/child/npobject_proxy.h ('k') | content/child/npobject_stub.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/child/npobject_proxy.h"
6
7 #include "content/child/np_channel_base.h"
8 #include "content/child/npapi/plugin_host.h"
9 #include "content/child/npapi/plugin_instance.h"
10 #include "content/child/npobject_util.h"
11 #include "content/child/plugin_messages.h"
12 #include "third_party/WebKit/public/web/WebBindings.h"
13
14 using WebKit::WebBindings;
15
16 namespace content {
17
18 struct NPObjectWrapper {
19 NPObject object;
20 NPObjectProxy* proxy;
21 };
22
23 NPClass NPObjectProxy::npclass_proxy_ = {
24 NP_CLASS_STRUCT_VERSION,
25 NPObjectProxy::NPAllocate,
26 NPObjectProxy::NPDeallocate,
27 NPObjectProxy::NPPInvalidate,
28 NPObjectProxy::NPHasMethod,
29 NPObjectProxy::NPInvoke,
30 NPObjectProxy::NPInvokeDefault,
31 NPObjectProxy::NPHasProperty,
32 NPObjectProxy::NPGetProperty,
33 NPObjectProxy::NPSetProperty,
34 NPObjectProxy::NPRemoveProperty,
35 NPObjectProxy::NPNEnumerate,
36 NPObjectProxy::NPNConstruct
37 };
38
39 NPObjectProxy* NPObjectProxy::GetProxy(NPObject* object) {
40 NPObjectProxy* proxy = NULL;
41
42 // Wrapper exists only for NPObjects that we had created.
43 if (&npclass_proxy_ == object->_class) {
44 NPObjectWrapper* wrapper = reinterpret_cast<NPObjectWrapper*>(object);
45 proxy = wrapper->proxy;
46 }
47
48 return proxy;
49 }
50
51 NPObject* NPObjectProxy::GetUnderlyingNPObject() {
52 return NULL;
53 }
54
55 IPC::Listener* NPObjectProxy::GetChannelListener() {
56 return static_cast<IPC::Listener*>(this);
57 }
58
59 NPObjectProxy::NPObjectProxy(
60 NPChannelBase* channel,
61 int route_id,
62 int render_view_id,
63 const GURL& page_url)
64 : channel_(channel),
65 route_id_(route_id),
66 render_view_id_(render_view_id),
67 page_url_(page_url) {
68 channel_->AddRoute(route_id, this, this);
69 }
70
71 NPObjectProxy::~NPObjectProxy() {
72 if (channel_.get()) {
73 // This NPObjectProxy instance is now invalid and should not be reused for
74 // requests initiated by plugins. We may receive requests for the
75 // same NPObject in the context of the outgoing NPObjectMsg_Release call.
76 // We should be creating new NPObjectProxy instances to wrap these
77 // NPObjects.
78 channel_->RemoveMappingForNPObjectProxy(route_id_);
79 channel_->RemoveRoute(route_id_);
80 Send(new NPObjectMsg_Release(route_id_));
81 }
82 }
83
84 NPObject* NPObjectProxy::Create(NPChannelBase* channel,
85 int route_id,
86 int render_view_id,
87 const GURL& page_url,
88 NPP owner) {
89 NPObjectWrapper* obj = reinterpret_cast<NPObjectWrapper*>(
90 WebBindings::createObject(owner, &npclass_proxy_));
91 obj->proxy = new NPObjectProxy(channel, route_id, render_view_id, page_url);
92 channel->AddMappingForNPObjectProxy(route_id, &obj->object);
93 return reinterpret_cast<NPObject*>(obj);
94 }
95
96 bool NPObjectProxy::Send(IPC::Message* msg) {
97 if (channel_.get())
98 return channel_->Send(msg);
99
100 delete msg;
101 return false;
102 }
103
104 NPObject* NPObjectProxy::NPAllocate(NPP, NPClass*) {
105 return reinterpret_cast<NPObject*>(new NPObjectWrapper);
106 }
107
108 void NPObjectProxy::NPDeallocate(NPObject* npObj) {
109 NPObjectWrapper* obj = reinterpret_cast<NPObjectWrapper*>(npObj);
110 delete obj->proxy;
111 delete obj;
112 }
113
114 bool NPObjectProxy::OnMessageReceived(const IPC::Message& msg) {
115 NOTREACHED();
116 return false;
117 }
118
119 void NPObjectProxy::OnChannelError() {
120 // Release our ref count of the plugin channel object, as it addrefs the
121 // process.
122 channel_ = NULL;
123 }
124
125 bool NPObjectProxy::NPHasMethod(NPObject *obj,
126 NPIdentifier name) {
127 if (obj == NULL)
128 return false;
129
130 bool result = false;
131 NPObjectProxy* proxy = GetProxy(obj);
132
133 if (!proxy) {
134 return obj->_class->hasMethod(obj, name);
135 }
136
137 NPIdentifier_Param name_param;
138 CreateNPIdentifierParam(name, &name_param);
139
140 proxy->Send(new NPObjectMsg_HasMethod(proxy->route_id(), name_param,
141 &result));
142 return result;
143 }
144
145 bool NPObjectProxy::NPInvoke(NPObject *obj,
146 NPIdentifier name,
147 const NPVariant *args,
148 uint32_t arg_count,
149 NPVariant *result) {
150 return NPInvokePrivate(0, obj, false, name, args, arg_count, result);
151 }
152
153 bool NPObjectProxy::NPInvokeDefault(NPObject *npobj,
154 const NPVariant *args,
155 uint32_t arg_count,
156 NPVariant *result) {
157 return NPInvokePrivate(0, npobj, true, 0, args, arg_count, result);
158 }
159
160 bool NPObjectProxy::NPInvokePrivate(NPP npp,
161 NPObject *obj,
162 bool is_default,
163 NPIdentifier name,
164 const NPVariant *args,
165 uint32_t arg_count,
166 NPVariant *np_result) {
167 if (obj == NULL)
168 return false;
169
170 NPObjectProxy* proxy = GetProxy(obj);
171 if (!proxy) {
172 if (is_default) {
173 return obj->_class->invokeDefault(obj, args, arg_count, np_result);
174 } else {
175 return obj->_class->invoke(obj, name, args, arg_count, np_result);
176 }
177 }
178
179 bool result = false;
180 int render_view_id = proxy->render_view_id_;
181 NPIdentifier_Param name_param;
182 if (is_default) {
183 // The data won't actually get used, but set it so we don't send random
184 // data.
185 name_param.identifier = NULL;
186 } else {
187 CreateNPIdentifierParam(name, &name_param);
188 }
189
190 // Note: This instance can get destroyed in the context of
191 // Send so addref the channel in this scope.
192 scoped_refptr<NPChannelBase> channel_copy = proxy->channel_;
193 std::vector<NPVariant_Param> args_param;
194 for (unsigned int i = 0; i < arg_count; ++i) {
195 NPVariant_Param param;
196 CreateNPVariantParam(args[i],
197 channel_copy.get(),
198 &param,
199 false,
200 render_view_id,
201 proxy->page_url_);
202 args_param.push_back(param);
203 }
204
205 NPVariant_Param param_result;
206 NPObjectMsg_Invoke* msg = new NPObjectMsg_Invoke(
207 proxy->route_id_, is_default, name_param, args_param, &param_result,
208 &result);
209
210 // If we're in the plugin process and this invoke leads to a dialog box, the
211 // plugin will hang the window hierarchy unless we pump the window message
212 // queue while waiting for a reply. We need to do this to simulate what
213 // happens when everything runs in-process (while calling MessageBox window
214 // messages are pumped).
215 if (IsPluginProcess() && proxy->channel()) {
216 msg->set_pump_messages_event(
217 proxy->channel()->GetModalDialogEvent(render_view_id));
218 }
219
220 GURL page_url = proxy->page_url_;
221 proxy->Send(msg);
222
223 // Send may delete proxy.
224 proxy = NULL;
225
226 if (!result)
227 return false;
228
229 CreateNPVariant(
230 param_result, channel_copy.get(), np_result, render_view_id, page_url);
231 return true;
232 }
233
234 bool NPObjectProxy::NPHasProperty(NPObject *obj,
235 NPIdentifier name) {
236 if (obj == NULL)
237 return false;
238
239 bool result = false;
240 NPObjectProxy* proxy = GetProxy(obj);
241 if (!proxy) {
242 return obj->_class->hasProperty(obj, name);
243 }
244
245 NPIdentifier_Param name_param;
246 CreateNPIdentifierParam(name, &name_param);
247
248 NPVariant_Param param;
249 proxy->Send(new NPObjectMsg_HasProperty(
250 proxy->route_id(), name_param, &result));
251
252 // Send may delete proxy.
253 proxy = NULL;
254
255 return result;
256 }
257
258 bool NPObjectProxy::NPGetProperty(NPObject *obj,
259 NPIdentifier name,
260 NPVariant *np_result) {
261 // Please refer to http://code.google.com/p/chromium/issues/detail?id=2556,
262 // which was a crash in the XStandard plugin during plugin shutdown. The
263 // crash occured because the plugin requests the plugin script object,
264 // which fails. The plugin does not check the result of the operation and
265 // invokes NPN_GetProperty on a NULL object which lead to the crash. If
266 // we observe similar crashes in other methods in the future, these null
267 // checks may have to be replicated in the other methods in this class.
268 if (obj == NULL)
269 return false;
270
271 NPObjectProxy* proxy = GetProxy(obj);
272 if (!proxy) {
273 return obj->_class->getProperty(obj, name, np_result);
274 }
275
276 bool result = false;
277 int render_view_id = proxy->render_view_id_;
278 NPIdentifier_Param name_param;
279 CreateNPIdentifierParam(name, &name_param);
280
281 NPVariant_Param param;
282 scoped_refptr<NPChannelBase> channel(proxy->channel_);
283
284 GURL page_url = proxy->page_url_;
285 proxy->Send(new NPObjectMsg_GetProperty(
286 proxy->route_id(), name_param, &param, &result));
287 // Send may delete proxy.
288 proxy = NULL;
289 if (!result)
290 return false;
291
292 CreateNPVariant(
293 param, channel.get(), np_result, render_view_id, page_url);
294
295 return true;
296 }
297
298 bool NPObjectProxy::NPSetProperty(NPObject *obj,
299 NPIdentifier name,
300 const NPVariant *value) {
301 if (obj == NULL)
302 return false;
303
304 NPObjectProxy* proxy = GetProxy(obj);
305 if (!proxy) {
306 return obj->_class->setProperty(obj, name, value);
307 }
308
309 bool result = false;
310 int render_view_id = proxy->render_view_id_;
311 NPIdentifier_Param name_param;
312 CreateNPIdentifierParam(name, &name_param);
313
314 NPVariant_Param value_param;
315 CreateNPVariantParam(
316 *value, proxy->channel(), &value_param, false, render_view_id,
317 proxy->page_url_);
318
319 proxy->Send(new NPObjectMsg_SetProperty(
320 proxy->route_id(), name_param, value_param, &result));
321 // Send may delete proxy.
322 proxy = NULL;
323
324 return result;
325 }
326
327 bool NPObjectProxy::NPRemoveProperty(NPObject *obj,
328 NPIdentifier name) {
329 if (obj == NULL)
330 return false;
331
332 bool result = false;
333 NPObjectProxy* proxy = GetProxy(obj);
334 if (!proxy) {
335 return obj->_class->removeProperty(obj, name);
336 }
337
338 NPIdentifier_Param name_param;
339 CreateNPIdentifierParam(name, &name_param);
340
341 NPVariant_Param param;
342 proxy->Send(new NPObjectMsg_RemoveProperty(
343 proxy->route_id(), name_param, &result));
344 // Send may delete proxy.
345 proxy = NULL;
346
347 return result;
348 }
349
350 void NPObjectProxy::NPPInvalidate(NPObject *obj) {
351 if (obj == NULL)
352 return;
353
354 NPObjectProxy* proxy = GetProxy(obj);
355 if (!proxy) {
356 obj->_class->invalidate(obj);
357 return;
358 }
359
360 proxy->Send(new NPObjectMsg_Invalidate(proxy->route_id()));
361 // Send may delete proxy.
362 proxy = NULL;
363 }
364
365 bool NPObjectProxy::NPNEnumerate(NPObject *obj,
366 NPIdentifier **value,
367 uint32_t *count) {
368 if (obj == NULL)
369 return false;
370
371 bool result = false;
372 NPObjectProxy* proxy = GetProxy(obj);
373 if (!proxy) {
374 if (obj->_class->structVersion >= NP_CLASS_STRUCT_VERSION_ENUM) {
375 return obj->_class->enumerate(obj, value, count);
376 } else {
377 return false;
378 }
379 }
380
381 std::vector<NPIdentifier_Param> value_param;
382 proxy->Send(new NPObjectMsg_Enumeration(
383 proxy->route_id(), &value_param, &result));
384 // Send may delete proxy.
385 proxy = NULL;
386
387 if (!result)
388 return false;
389
390 *count = static_cast<unsigned int>(value_param.size());
391 *value = static_cast<NPIdentifier *>(
392 PluginHost::Singleton()->host_functions()->memalloc(
393 sizeof(NPIdentifier) * *count));
394 for (unsigned int i = 0; i < *count; ++i)
395 (*value)[i] = CreateNPIdentifier(value_param[i]);
396
397 return true;
398 }
399
400 bool NPObjectProxy::NPNConstruct(NPObject *obj,
401 const NPVariant *args,
402 uint32_t arg_count,
403 NPVariant *np_result) {
404 if (obj == NULL)
405 return false;
406
407 NPObjectProxy* proxy = GetProxy(obj);
408 if (!proxy) {
409 if (obj->_class->structVersion >= NP_CLASS_STRUCT_VERSION_CTOR) {
410 return obj->_class->construct(obj, args, arg_count, np_result);
411 } else {
412 return false;
413 }
414 }
415
416 bool result = false;
417 int render_view_id = proxy->render_view_id_;
418
419 // Note: This instance can get destroyed in the context of
420 // Send so addref the channel in this scope.
421 scoped_refptr<NPChannelBase> channel_copy = proxy->channel_;
422 std::vector<NPVariant_Param> args_param;
423 for (unsigned int i = 0; i < arg_count; ++i) {
424 NPVariant_Param param;
425 CreateNPVariantParam(args[i],
426 channel_copy.get(),
427 &param,
428 false,
429 render_view_id,
430 proxy->page_url_);
431 args_param.push_back(param);
432 }
433
434 NPVariant_Param param_result;
435 NPObjectMsg_Construct* msg = new NPObjectMsg_Construct(
436 proxy->route_id_, args_param, &param_result, &result);
437
438 // See comment in NPObjectProxy::NPInvokePrivate.
439 if (IsPluginProcess() && proxy->channel()) {
440 msg->set_pump_messages_event(
441 proxy->channel()->GetModalDialogEvent(proxy->render_view_id_));
442 }
443
444 GURL page_url = proxy->page_url_;
445 proxy->Send(msg);
446
447 // Send may delete proxy.
448 proxy = NULL;
449
450 if (!result)
451 return false;
452
453 CreateNPVariant(
454 param_result, channel_copy.get(), np_result, render_view_id, page_url);
455 return true;
456 }
457
458 bool NPObjectProxy::NPNEvaluate(NPP npp,
459 NPObject *obj,
460 NPString *script,
461 NPVariant *result_var) {
462 NPObjectProxy* proxy = GetProxy(obj);
463 if (!proxy) {
464 return false;
465 }
466
467 bool result = false;
468 int render_view_id = proxy->render_view_id_;
469 bool popups_allowed = false;
470
471 if (npp) {
472 PluginInstance* plugin_instance =
473 reinterpret_cast<PluginInstance*>(npp->ndata);
474 if (plugin_instance)
475 popups_allowed = plugin_instance->popups_allowed();
476 }
477
478 NPVariant_Param result_param;
479 std::string script_str = std::string(
480 script->UTF8Characters, script->UTF8Length);
481
482 NPObjectMsg_Evaluate* msg = new NPObjectMsg_Evaluate(proxy->route_id(),
483 script_str,
484 popups_allowed,
485 &result_param,
486 &result);
487
488 // See comment in NPObjectProxy::NPInvokePrivate.
489 if (IsPluginProcess() && proxy->channel()) {
490 msg->set_pump_messages_event(
491 proxy->channel()->GetModalDialogEvent(render_view_id));
492 }
493 scoped_refptr<NPChannelBase> channel(proxy->channel_);
494
495 GURL page_url = proxy->page_url_;
496 proxy->Send(msg);
497 // Send may delete proxy.
498 proxy = NULL;
499 if (!result)
500 return false;
501
502 CreateNPVariant(
503 result_param, channel.get(), result_var, render_view_id, page_url);
504 return true;
505 }
506
507 } // namespace content
OLDNEW
« no previous file with comments | « content/child/npobject_proxy.h ('k') | content/child/npobject_stub.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698