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

Side by Side Diff: chrome/plugin/npobject_proxy.cc

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

Powered by Google App Engine
This is Rietveld 408576698