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

Side by Side Diff: chrome/plugin/npobject_stub.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_stub.h ('k') | chrome/plugin/npobject_util.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) 2011 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_stub.h"
6
7 #include "chrome/plugin/npobject_util.h"
8 #include "chrome/plugin/plugin_channel_base.h"
9 #include "chrome/plugin/plugin_thread.h"
10 #include "content/common/content_client.h"
11 #include "content/common/plugin_messages.h"
12 #include "third_party/npapi/bindings/npapi.h"
13 #include "third_party/npapi/bindings/npruntime.h"
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h"
15 #include "webkit/plugins/npapi/plugin_constants_win.h"
16
17 using WebKit::WebBindings;
18
19 NPObjectStub::NPObjectStub(
20 NPObject* npobject,
21 PluginChannelBase* channel,
22 int route_id,
23 gfx::NativeViewId containing_window,
24 const GURL& page_url)
25 : npobject_(npobject),
26 channel_(channel),
27 route_id_(route_id),
28 containing_window_(containing_window),
29 page_url_(page_url) {
30 channel_->AddRoute(route_id, this, this);
31
32 // We retain the object just as PluginHost does if everything was in-process.
33 WebBindings::retainObject(npobject_);
34 }
35
36 NPObjectStub::~NPObjectStub() {
37 channel_->RemoveRoute(route_id_);
38 if (npobject_)
39 WebBindings::releaseObject(npobject_);
40 }
41
42 bool NPObjectStub::Send(IPC::Message* msg) {
43 return channel_->Send(msg);
44 }
45
46 void NPObjectStub::OnPluginDestroyed() {
47 // We null out the underlying NPObject pointer since it's not valid anymore (
48 // ScriptController manually deleted the object). As a result,
49 // OnMessageReceived won't dispatch any more messages. Since this includes
50 // OnRelease, this object won't get deleted until OnChannelError which might
51 // not happen for a long time if this renderer process has a long lived
52 // plugin instance to the same process. So we delete this object manually.
53 npobject_ = NULL;
54 MessageLoop::current()->DeleteSoon(FROM_HERE, this);
55 }
56
57 NPObject* NPObjectStub::GetUnderlyingNPObject() {
58 return npobject_;
59 }
60
61 IPC::Channel::Listener* NPObjectStub::GetChannelListener() {
62 return static_cast<IPC::Channel::Listener*>(this);
63 }
64
65 bool NPObjectStub::OnMessageReceived(const IPC::Message& msg) {
66 content::GetContentClient()->SetActiveURL(page_url_);
67
68 if (!npobject_) {
69 if (msg.is_sync()) {
70 // The object could be garbage because the frame has gone away, so
71 // just send an error reply to the caller.
72 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg);
73 reply->set_reply_error();
74 Send(reply);
75 }
76
77 return true;
78 }
79
80 bool handled = true;
81 IPC_BEGIN_MESSAGE_MAP(NPObjectStub, msg)
82 IPC_MESSAGE_HANDLER_DELAY_REPLY(NPObjectMsg_Release, OnRelease);
83 IPC_MESSAGE_HANDLER(NPObjectMsg_HasMethod, OnHasMethod);
84 IPC_MESSAGE_HANDLER_DELAY_REPLY(NPObjectMsg_Invoke, OnInvoke);
85 IPC_MESSAGE_HANDLER(NPObjectMsg_HasProperty, OnHasProperty);
86 IPC_MESSAGE_HANDLER(NPObjectMsg_GetProperty, OnGetProperty);
87 IPC_MESSAGE_HANDLER_DELAY_REPLY(NPObjectMsg_SetProperty, OnSetProperty);
88 IPC_MESSAGE_HANDLER(NPObjectMsg_RemoveProperty, OnRemoveProperty);
89 IPC_MESSAGE_HANDLER(NPObjectMsg_Invalidate, OnInvalidate);
90 IPC_MESSAGE_HANDLER(NPObjectMsg_Enumeration, OnEnumeration);
91 IPC_MESSAGE_HANDLER_DELAY_REPLY(NPObjectMsg_Construct, OnConstruct);
92 IPC_MESSAGE_HANDLER_DELAY_REPLY(NPObjectMsg_Evaluate, OnEvaluate);
93 IPC_MESSAGE_UNHANDLED(handled = false)
94 IPC_END_MESSAGE_MAP()
95 DCHECK(handled);
96 return handled;
97 }
98
99 void NPObjectStub::OnChannelError() {
100 // If npobject_ is NULLed out, that means a DeleteSoon is happening.
101 if (npobject_)
102 delete this;
103 }
104
105 void NPObjectStub::OnRelease(IPC::Message* reply_msg) {
106 Send(reply_msg);
107 delete this;
108 }
109
110 void NPObjectStub::OnHasMethod(const NPIdentifier_Param& name,
111 bool* result) {
112 NPIdentifier id = CreateNPIdentifier(name);
113 // If we're in the plugin process, then the stub is holding onto an NPObject
114 // from the plugin, so all function calls on it need to go through the
115 // functions in NPClass. If we're in the renderer process, then we just call
116 // the NPN_ functions.
117 if (IsPluginProcess()) {
118 if (npobject_->_class->hasMethod) {
119 *result = npobject_->_class->hasMethod(npobject_, id);
120 } else {
121 *result = false;
122 }
123 } else {
124 *result = WebBindings::hasMethod(0, npobject_, id);
125 }
126 }
127
128 void NPObjectStub::OnInvoke(bool is_default,
129 const NPIdentifier_Param& method,
130 const std::vector<NPVariant_Param>& args,
131 IPC::Message* reply_msg) {
132 scoped_refptr<PluginChannelBase> local_channel = channel_;
133 bool return_value = false;
134 NPVariant_Param result_param;
135 NPVariant result_var;
136
137 VOID_TO_NPVARIANT(result_var);
138 result_param.type = NPVARIANT_PARAM_VOID;
139
140 int arg_count = static_cast<int>(args.size());
141 NPVariant* args_var = new NPVariant[arg_count];
142 for (int i = 0; i < arg_count; ++i) {
143 if (!CreateNPVariant(
144 args[i], local_channel, &(args_var[i]), containing_window_,
145 page_url_)) {
146 NPObjectMsg_Invoke::WriteReplyParams(reply_msg, result_param,
147 return_value);
148 local_channel->Send(reply_msg);
149 return;
150 }
151 }
152
153 if (is_default) {
154 if (IsPluginProcess()) {
155 if (npobject_->_class->invokeDefault) {
156 return_value = npobject_->_class->invokeDefault(
157 npobject_, args_var, arg_count, &result_var);
158 } else {
159 return_value = false;
160 }
161 } else {
162 return_value = WebBindings::invokeDefault(
163 0, npobject_, args_var, arg_count, &result_var);
164 }
165 } else {
166 NPIdentifier id = CreateNPIdentifier(method);
167 if (IsPluginProcess()) {
168 if (npobject_->_class->invoke) {
169 return_value = npobject_->_class->invoke(
170 npobject_, id, args_var, arg_count, &result_var);
171 } else {
172 return_value = false;
173 }
174 } else {
175 return_value = WebBindings::invoke(
176 0, npobject_, id, args_var, arg_count, &result_var);
177 }
178 }
179
180 for (int i = 0; i < arg_count; ++i)
181 WebBindings::releaseVariantValue(&(args_var[i]));
182
183 delete[] args_var;
184
185 CreateNPVariantParam(
186 result_var, local_channel, &result_param, true, containing_window_,
187 page_url_);
188 NPObjectMsg_Invoke::WriteReplyParams(reply_msg, result_param, return_value);
189 local_channel->Send(reply_msg);
190 }
191
192 void NPObjectStub::OnHasProperty(const NPIdentifier_Param& name,
193 bool* result) {
194 NPIdentifier id = CreateNPIdentifier(name);
195 if (IsPluginProcess()) {
196 if (npobject_->_class->hasProperty) {
197 *result = npobject_->_class->hasProperty(npobject_, id);
198 } else {
199 *result = false;
200 }
201 } else {
202 *result = WebBindings::hasProperty(0, npobject_, id);
203 }
204 }
205
206 void NPObjectStub::OnGetProperty(const NPIdentifier_Param& name,
207 NPVariant_Param* property,
208 bool* result) {
209 NPVariant result_var;
210 VOID_TO_NPVARIANT(result_var);
211 NPIdentifier id = CreateNPIdentifier(name);
212
213 if (IsPluginProcess()) {
214 if (npobject_->_class->getProperty) {
215 *result = npobject_->_class->getProperty(npobject_, id, &result_var);
216 } else {
217 *result = false;
218 }
219 } else {
220 *result = WebBindings::getProperty(0, npobject_, id, &result_var);
221 }
222
223 CreateNPVariantParam(
224 result_var, channel_, property, true, containing_window_, page_url_);
225 }
226
227 void NPObjectStub::OnSetProperty(const NPIdentifier_Param& name,
228 const NPVariant_Param& property,
229 IPC::Message* reply_msg) {
230 bool result = false;
231 NPVariant result_var;
232 VOID_TO_NPVARIANT(result_var);
233 NPIdentifier id = CreateNPIdentifier(name);
234 NPVariant property_var;
235 if (!CreateNPVariant(
236 property, channel_, &property_var, containing_window_, page_url_)) {
237 NPObjectMsg_SetProperty::WriteReplyParams(reply_msg, result);
238 channel_->Send(reply_msg);
239 return;
240 }
241
242 if (IsPluginProcess()) {
243 if (npobject_->_class->setProperty) {
244 #if defined(OS_WIN)
245 static std::wstring filename = StringToLowerASCII(
246 PluginThread::current()->plugin_path().BaseName().value());
247 static NPIdentifier fullscreen =
248 WebBindings::getStringIdentifier("fullScreen");
249 if (filename == webkit::npapi::kNewWMPPlugin && id == fullscreen) {
250 // Workaround for bug 15985, which is if Flash causes WMP to go
251 // full screen a deadlock can occur when WMP calls SetFocus.
252 NPObjectMsg_SetProperty::WriteReplyParams(reply_msg, true);
253 Send(reply_msg);
254 reply_msg = NULL;
255 }
256 #endif
257 result = npobject_->_class->setProperty(npobject_, id, &property_var);
258 } else {
259 result = false;
260 }
261 } else {
262 result = WebBindings::setProperty(0, npobject_, id, &property_var);
263 }
264
265 WebBindings::releaseVariantValue(&property_var);
266
267 if (reply_msg) {
268 NPObjectMsg_SetProperty::WriteReplyParams(reply_msg, result);
269 Send(reply_msg);
270 }
271 }
272
273 void NPObjectStub::OnRemoveProperty(const NPIdentifier_Param& name,
274 bool* result) {
275 NPIdentifier id = CreateNPIdentifier(name);
276 if (IsPluginProcess()) {
277 if (npobject_->_class->removeProperty) {
278 *result = npobject_->_class->removeProperty(npobject_, id);
279 } else {
280 *result = false;
281 }
282 } else {
283 *result = WebBindings::removeProperty(0, npobject_, id);
284 }
285 }
286
287 void NPObjectStub::OnInvalidate() {
288 if (!IsPluginProcess()) {
289 NOTREACHED() << "Should only be called on NPObjects in the plugin";
290 return;
291 }
292
293 if (!npobject_->_class->invalidate)
294 return;
295
296 npobject_->_class->invalidate(npobject_);
297 }
298
299 void NPObjectStub::OnEnumeration(std::vector<NPIdentifier_Param>* value,
300 bool* result) {
301 NPIdentifier* value_np = NULL;
302 unsigned int count = 0;
303 if (!IsPluginProcess()) {
304 *result = WebBindings::enumerate(0, npobject_, &value_np, &count);
305 } else {
306 if (npobject_->_class->structVersion < NP_CLASS_STRUCT_VERSION_ENUM ||
307 !npobject_->_class->enumerate) {
308 *result = false;
309 return;
310 }
311
312 *result = npobject_->_class->enumerate(npobject_, &value_np, &count);
313 }
314
315 if (!*result)
316 return;
317
318 for (unsigned int i = 0; i < count; ++i) {
319 NPIdentifier_Param param;
320 CreateNPIdentifierParam(value_np[i], &param);
321 value->push_back(param);
322 }
323
324 NPN_MemFree(value_np);
325 }
326
327 void NPObjectStub::OnConstruct(const std::vector<NPVariant_Param>& args,
328 IPC::Message* reply_msg) {
329 scoped_refptr<PluginChannelBase> local_channel = channel_;
330 bool return_value = false;
331 NPVariant_Param result_param;
332 NPVariant result_var;
333
334 VOID_TO_NPVARIANT(result_var);
335
336 int arg_count = static_cast<int>(args.size());
337 NPVariant* args_var = new NPVariant[arg_count];
338 for (int i = 0; i < arg_count; ++i) {
339 if (!CreateNPVariant(
340 args[i], local_channel, &(args_var[i]), containing_window_,
341 page_url_)) {
342 NPObjectMsg_Invoke::WriteReplyParams(reply_msg, result_param,
343 return_value);
344 local_channel->Send(reply_msg);
345 return;
346 }
347 }
348
349 if (IsPluginProcess()) {
350 if (npobject_->_class->structVersion >= NP_CLASS_STRUCT_VERSION_CTOR &&
351 npobject_->_class->construct) {
352 return_value = npobject_->_class->construct(
353 npobject_, args_var, arg_count, &result_var);
354 } else {
355 return_value = false;
356 }
357 } else {
358 return_value = WebBindings::construct(
359 0, npobject_, args_var, arg_count, &result_var);
360 }
361
362 for (int i = 0; i < arg_count; ++i)
363 WebBindings::releaseVariantValue(&(args_var[i]));
364
365 delete[] args_var;
366
367 CreateNPVariantParam(
368 result_var, local_channel, &result_param, true, containing_window_,
369 page_url_);
370 NPObjectMsg_Invoke::WriteReplyParams(reply_msg, result_param, return_value);
371 local_channel->Send(reply_msg);
372 }
373
374 void NPObjectStub::OnEvaluate(const std::string& script,
375 bool popups_allowed,
376 IPC::Message* reply_msg) {
377 if (IsPluginProcess()) {
378 NOTREACHED() << "Should only be called on NPObjects in the renderer";
379 return;
380 }
381
382 // Grab a reference to the underlying channel, as the NPObjectStub
383 // instance can be destroyed in the context of NPN_Evaluate. This
384 // can happen if the containing plugin instance is destroyed in
385 // NPN_Evaluate.
386 scoped_refptr<PluginChannelBase> local_channel = channel_;
387
388 NPVariant result_var;
389 NPString script_string;
390 script_string.UTF8Characters = script.c_str();
391 script_string.UTF8Length = static_cast<unsigned int>(script.length());
392
393 bool return_value = WebBindings::evaluateHelper(0, popups_allowed, npobject_,
394 &script_string, &result_var);
395
396 NPVariant_Param result_param;
397 CreateNPVariantParam(
398 result_var, local_channel, &result_param, true, containing_window_,
399 page_url_);
400 NPObjectMsg_Evaluate::WriteReplyParams(reply_msg, result_param, return_value);
401 local_channel->Send(reply_msg);
402 }
OLDNEW
« no previous file with comments | « chrome/plugin/npobject_stub.h ('k') | chrome/plugin/npobject_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698