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

Side by Side Diff: webkit/plugins/ppapi/message_channel.cc

Issue 11490014: PPAPI: Make Messaging not PostTask and copy when out-of-process. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years 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
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 "webkit/plugins/ppapi/message_channel.h" 5 #include "webkit/plugins/ppapi/message_channel.h"
6 6
7 #include <cstdlib> 7 #include <cstdlib>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/message_loop.h" 12 #include "base/message_loop.h"
13 #include "ppapi/shared_impl/ppapi_globals.h" 13 #include "ppapi/shared_impl/ppapi_globals.h"
14 #include "ppapi/shared_impl/var.h" 14 #include "ppapi/shared_impl/var.h"
15 #include "ppapi/shared_impl/var_tracker.h" 15 #include "ppapi/shared_impl/var_tracker.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMMessageEvent.h" 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMMessageEvent.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h" 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
23 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSerialize dScriptValue.h" 23 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSerialize dScriptValue.h"
24 #include "v8/include/v8.h" 24 #include "v8/include/v8.h"
25 #include "webkit/plugins/ppapi/host_array_buffer_var.h" 25 #include "webkit/plugins/ppapi/host_array_buffer_var.h"
26 #include "webkit/plugins/ppapi/npapi_glue.h" 26 #include "webkit/plugins/ppapi/npapi_glue.h"
27 #include "webkit/plugins/ppapi/plugin_module.h"
27 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" 28 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
28 29
29 using ppapi::ArrayBufferVar; 30 using ppapi::ArrayBufferVar;
30 using ppapi::PpapiGlobals; 31 using ppapi::PpapiGlobals;
31 using ppapi::StringVar; 32 using ppapi::StringVar;
32 using WebKit::WebBindings; 33 using WebKit::WebBindings;
33 using WebKit::WebElement; 34 using WebKit::WebElement;
34 using WebKit::WebDOMEvent; 35 using WebKit::WebDOMEvent;
35 using WebKit::WebDOMMessageEvent; 36 using WebKit::WebDOMMessageEvent;
36 using WebKit::WebPluginContainer; 37 using WebKit::WebPluginContainer;
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 // MessageChannel -------------------------------------------------------------- 324 // MessageChannel --------------------------------------------------------------
324 MessageChannel::MessageChannelNPObject::MessageChannelNPObject() { 325 MessageChannel::MessageChannelNPObject::MessageChannelNPObject() {
325 } 326 }
326 327
327 MessageChannel::MessageChannelNPObject::~MessageChannelNPObject() {} 328 MessageChannel::MessageChannelNPObject::~MessageChannelNPObject() {}
328 329
329 MessageChannel::MessageChannel(PluginInstance* instance) 330 MessageChannel::MessageChannel(PluginInstance* instance)
330 : instance_(instance), 331 : instance_(instance),
331 passthrough_object_(NULL), 332 passthrough_object_(NULL),
332 np_object_(NULL), 333 np_object_(NULL),
333 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { 334 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
335 did_create_finished_(false) {
334 // Now create an NPObject for receiving calls to postMessage. This sets the 336 // Now create an NPObject for receiving calls to postMessage. This sets the
335 // reference count to 1. We release it in the destructor. 337 // reference count to 1. We release it in the destructor.
336 NPObject* obj = WebBindings::createObject(NULL, &message_channel_class); 338 NPObject* obj = WebBindings::createObject(NULL, &message_channel_class);
337 DCHECK(obj); 339 DCHECK(obj);
338 np_object_ = static_cast<MessageChannel::MessageChannelNPObject*>(obj); 340 np_object_ = static_cast<MessageChannel::MessageChannelNPObject*>(obj);
339 np_object_->message_channel = weak_ptr_factory_.GetWeakPtr(); 341 np_object_->message_channel = weak_ptr_factory_.GetWeakPtr();
340 } 342 }
341 343
342 void MessageChannel::PostMessageToJavaScript(PP_Var message_data) { 344 void MessageChannel::PostMessageToJavaScript(PP_Var message_data) {
343 // Serialize the message data. 345 // Serialize the message data.
344 v8::HandleScope scope; 346 v8::HandleScope scope;
345 // Because V8 is probably not on the stack for Native->JS calls, we need to 347 // Because V8 is probably not on the stack for Native->JS calls, we need to
346 // enter the appropriate context for the plugin. 348 // enter the appropriate context for the plugin.
347 v8::Local<v8::Context> context = 349 v8::Local<v8::Context> context =
348 instance_->container()->element().document().frame()-> 350 instance_->container()->element().document().frame()->
349 mainWorldScriptContext(); 351 mainWorldScriptContext();
350 v8::Context::Scope context_scope(context); 352 v8::Context::Scope context_scope(context);
351 353
352 v8::Local<v8::Value> v8_val; 354 v8::Local<v8::Value> v8_val;
353 if (!PPVarToV8Value(message_data, &v8_val)) { 355 if (!PPVarToV8Value(message_data, &v8_val)) {
354 NOTREACHED(); 356 NOTREACHED();
355 return; 357 return;
356 } 358 }
357 359
358 WebSerializedScriptValue serialized_val = 360 WebSerializedScriptValue serialized_val =
359 WebSerializedScriptValue::serialize(v8_val); 361 WebSerializedScriptValue::serialize(v8_val);
360 362
363 if (instance_->module()->IsProxied()) {
364 // The proxy sent an asynchronous message, so the plugin is already
365 // unblocked. Therefore, there's no need to PostTask.
dmichael (off chromium) 2012/12/10 22:02:52 This comment probably belongs in the first branch
teravest 2012/12/10 22:30:59 Done.
366 if (did_create_finished_) {
367 DCHECK(early_message_queue_.size() == 0);
368 PostMessageToJavaScriptImpl(serialized_val);
369 } else {
370 early_message_queue_.push_back(serialized_val);
dmichael (off chromium) 2012/12/10 22:02:52 Probably worth a brief comment why we have to defe
teravest 2012/12/10 22:30:59 Done.
371 }
372 } else {
373 MessageLoop::current()->PostTask(
374 FROM_HERE,
375 base::Bind(&MessageChannel::PostMessageToJavaScriptImpl,
376 weak_ptr_factory_.GetWeakPtr(),
377 serialized_val));
378 }
379 }
380
381 void MessageChannel::DidCreateFinished() {
382 // We PostTask here instead of draining the message queue directly
383 // since we haven't finished initializing the WebPluginImpl yet, so
384 // the plugin isn't available in the DOM.
361 MessageLoop::current()->PostTask( 385 MessageLoop::current()->PostTask(
362 FROM_HERE, 386 FROM_HERE,
363 base::Bind(&MessageChannel::PostMessageToJavaScriptImpl, 387 base::Bind(&MessageChannel::DrainEarlyMessageQueue,
364 weak_ptr_factory_.GetWeakPtr(), 388 weak_ptr_factory_.GetWeakPtr()));
365 serialized_val)); 389 }
390
391 void MessageChannel::DrainEarlyMessageQueue() {
dmichael (off chromium) 2012/12/10 22:02:52 Might be worth doing: DCHECK(!did_create_finished_
teravest 2012/12/10 22:30:59 Done.
392 while (!early_message_queue_.empty()) {
393 PostMessageToJavaScriptImpl(early_message_queue_.front());
394 early_message_queue_.pop_front();
dmichael (off chromium) 2012/12/10 22:02:52 If there's any chance of re-entry, you'd probably
teravest 2012/12/10 22:30:59 I think it's safe as is... On 2012/12/10 22:02:52
dmichael (off chromium) 2012/12/10 22:49:47 Yes, I wasn't thinking straight; the problem I was
395 }
396 did_create_finished_ = true;
366 } 397 }
367 398
368 void MessageChannel::PostMessageToJavaScriptImpl( 399 void MessageChannel::PostMessageToJavaScriptImpl(
369 const WebSerializedScriptValue& message_data) { 400 const WebSerializedScriptValue& message_data) {
370 DCHECK(instance_); 401 DCHECK(instance_);
371 402
372 WebPluginContainer* container = instance_->container(); 403 WebPluginContainer* container = instance_->container();
373 // It's possible that container() is NULL if the plugin has been removed from 404 // It's possible that container() is NULL if the plugin has been removed from
374 // the DOM (but the PluginInstance is not destroyed yet). 405 // the DOM (but the PluginInstance is not destroyed yet).
375 if (!container) 406 if (!container)
(...skipping 15 matching lines...) Expand all
391 // http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html 422 // http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html
392 // This currently behaves like Web Workers. On Firefox, Chrome, and Safari 423 // This currently behaves like Web Workers. On Firefox, Chrome, and Safari
393 // at least, postMessage on Workers does not provide the origin or source. 424 // at least, postMessage on Workers does not provide the origin or source.
394 // TODO(dmichael): Add origin if we change to a more iframe-like origin 425 // TODO(dmichael): Add origin if we change to a more iframe-like origin
395 // policy (see crbug.com/81537) 426 // policy (see crbug.com/81537)
396 427
397 container->element().dispatchEvent(msg_event); 428 container->element().dispatchEvent(msg_event);
398 } 429 }
399 430
400 void MessageChannel::PostMessageToNative(PP_Var message_data) { 431 void MessageChannel::PostMessageToNative(PP_Var message_data) {
401 // Make a copy of the message data for the Task we will run. 432 if (instance_->module()->IsProxied()) {
402 PP_Var var_copy(CopyPPVar(message_data)); 433 // In the proxied case, the copy will happen via serializiation, and the
434 // message is asynchronous. Therefore there's no need to copy the Var, nor
435 // to PostTask.
436 PostMessageToNativeImpl(message_data);
437 } else {
438 // Make a copy of the message data for the Task we will run.
439 PP_Var var_copy(CopyPPVar(message_data));
403 440
404 MessageLoop::current()->PostTask(FROM_HERE, 441 MessageLoop::current()->PostTask(FROM_HERE,
405 base::Bind(&MessageChannel::PostMessageToNativeImpl, 442 base::Bind(&MessageChannel::PostMessageToNativeImpl,
406 weak_ptr_factory_.GetWeakPtr(), 443 weak_ptr_factory_.GetWeakPtr(),
407 var_copy)); 444 var_copy));
445 }
408 } 446 }
409 447
410 void MessageChannel::PostMessageToNativeImpl(PP_Var message_data) { 448 void MessageChannel::PostMessageToNativeImpl(PP_Var message_data) {
411 instance_->HandleMessage(message_data); 449 instance_->HandleMessage(message_data);
412 } 450 }
413 451
414 MessageChannel::~MessageChannel() { 452 MessageChannel::~MessageChannel() {
415 WebBindings::releaseObject(np_object_); 453 WebBindings::releaseObject(np_object_);
416 if (passthrough_object_) 454 if (passthrough_object_)
417 WebBindings::releaseObject(passthrough_object_); 455 WebBindings::releaseObject(passthrough_object_);
(...skipping 10 matching lines...) Expand all
428 // invokes: 466 // invokes:
429 // SetPassthroughObject(passthrough_object()); 467 // SetPassthroughObject(passthrough_object());
430 if (passthrough_object_) 468 if (passthrough_object_)
431 WebBindings::releaseObject(passthrough_object_); 469 WebBindings::releaseObject(passthrough_object_);
432 470
433 passthrough_object_ = passthrough; 471 passthrough_object_ = passthrough;
434 } 472 }
435 473
436 } // namespace ppapi 474 } // namespace ppapi
437 } // namespace webkit 475 } // namespace webkit
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698