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

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: Fixed NaCl plugins 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 queue_js_messages_(true) {
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 if (queue_js_messages_) {
365 // We can't just PostTask here; the messages would arrive out of
366 // order. Instead, we queue them up until we're ready to post
367 // them.
368 early_message_queue_.push_back(serialized_val);
369 } else {
370 // The proxy sent an asynchronous message, so the plugin is already
371 // unblocked. Therefore, there's no need to PostTask.
372 DCHECK(early_message_queue_.size() == 0);
373 PostMessageToJavaScriptImpl(serialized_val);
374 }
375 } else {
376 MessageLoop::current()->PostTask(
377 FROM_HERE,
378 base::Bind(&MessageChannel::PostMessageToJavaScriptImpl,
379 weak_ptr_factory_.GetWeakPtr(),
380 serialized_val));
381 }
382 }
383
384 void MessageChannel::EndQueueingJavaScriptMessages() {
385 // We PostTask here instead of draining the message queue directly
386 // since we haven't finished initializing the WebPluginImpl yet, so
387 // the plugin isn't available in the DOM.
388 DCHECK(queue_js_messages_);
dmichael (off chromium) 2012/12/11 18:55:55 Do you think there's any chance of calling QueueJa
teravest 2012/12/11 21:32:12 I cleaned this up by making an enum of the possibl
361 MessageLoop::current()->PostTask( 389 MessageLoop::current()->PostTask(
362 FROM_HERE, 390 FROM_HERE,
363 base::Bind(&MessageChannel::PostMessageToJavaScriptImpl, 391 base::Bind(&MessageChannel::DrainEarlyMessageQueue,
364 weak_ptr_factory_.GetWeakPtr(), 392 weak_ptr_factory_.GetWeakPtr()));
365 serialized_val)); 393 }
394
395 void MessageChannel::QueueJavaScriptMessages() {
396 DCHECK(!queue_js_messages_);
397 queue_js_messages_ = true;
398 }
399
400 void MessageChannel::DrainEarlyMessageQueue() {
401 DCHECK(queue_js_messages_);
402 while (!early_message_queue_.empty()) {
403 PostMessageToJavaScriptImpl(early_message_queue_.front());
404 early_message_queue_.pop_front();
405 }
406 queue_js_messages_ = false;
366 } 407 }
367 408
368 void MessageChannel::PostMessageToJavaScriptImpl( 409 void MessageChannel::PostMessageToJavaScriptImpl(
369 const WebSerializedScriptValue& message_data) { 410 const WebSerializedScriptValue& message_data) {
370 DCHECK(instance_); 411 DCHECK(instance_);
371 412
372 WebPluginContainer* container = instance_->container(); 413 WebPluginContainer* container = instance_->container();
373 // It's possible that container() is NULL if the plugin has been removed from 414 // It's possible that container() is NULL if the plugin has been removed from
374 // the DOM (but the PluginInstance is not destroyed yet). 415 // the DOM (but the PluginInstance is not destroyed yet).
375 if (!container) 416 if (!container)
(...skipping 15 matching lines...) Expand all
391 // http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html 432 // http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html
392 // This currently behaves like Web Workers. On Firefox, Chrome, and Safari 433 // This currently behaves like Web Workers. On Firefox, Chrome, and Safari
393 // at least, postMessage on Workers does not provide the origin or source. 434 // 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 435 // TODO(dmichael): Add origin if we change to a more iframe-like origin
395 // policy (see crbug.com/81537) 436 // policy (see crbug.com/81537)
396 437
397 container->element().dispatchEvent(msg_event); 438 container->element().dispatchEvent(msg_event);
398 } 439 }
399 440
400 void MessageChannel::PostMessageToNative(PP_Var message_data) { 441 void MessageChannel::PostMessageToNative(PP_Var message_data) {
401 // Make a copy of the message data for the Task we will run. 442 if (instance_->module()->IsProxied()) {
402 PP_Var var_copy(CopyPPVar(message_data)); 443 // In the proxied case, the copy will happen via serializiation, and the
444 // message is asynchronous. Therefore there's no need to copy the Var, nor
445 // to PostTask.
446 PostMessageToNativeImpl(message_data);
447 } else {
448 // Make a copy of the message data for the Task we will run.
449 PP_Var var_copy(CopyPPVar(message_data));
403 450
404 MessageLoop::current()->PostTask(FROM_HERE, 451 MessageLoop::current()->PostTask(FROM_HERE,
405 base::Bind(&MessageChannel::PostMessageToNativeImpl, 452 base::Bind(&MessageChannel::PostMessageToNativeImpl,
406 weak_ptr_factory_.GetWeakPtr(), 453 weak_ptr_factory_.GetWeakPtr(),
407 var_copy)); 454 var_copy));
455 }
408 } 456 }
409 457
410 void MessageChannel::PostMessageToNativeImpl(PP_Var message_data) { 458 void MessageChannel::PostMessageToNativeImpl(PP_Var message_data) {
411 instance_->HandleMessage(message_data); 459 instance_->HandleMessage(message_data);
412 } 460 }
413 461
414 MessageChannel::~MessageChannel() { 462 MessageChannel::~MessageChannel() {
415 WebBindings::releaseObject(np_object_); 463 WebBindings::releaseObject(np_object_);
416 if (passthrough_object_) 464 if (passthrough_object_)
417 WebBindings::releaseObject(passthrough_object_); 465 WebBindings::releaseObject(passthrough_object_);
(...skipping 10 matching lines...) Expand all
428 // invokes: 476 // invokes:
429 // SetPassthroughObject(passthrough_object()); 477 // SetPassthroughObject(passthrough_object());
430 if (passthrough_object_) 478 if (passthrough_object_)
431 WebBindings::releaseObject(passthrough_object_); 479 WebBindings::releaseObject(passthrough_object_);
432 480
433 passthrough_object_ = passthrough; 481 passthrough_object_ = passthrough;
434 } 482 }
435 483
436 } // namespace ppapi 484 } // namespace ppapi
437 } // namespace webkit 485 } // namespace webkit
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698