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

Side by Side Diff: content/renderer/pepper/message_channel.cc

Issue 605593002: PPAPI: Support sending browser-hosted resources synchronously Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix content_browsertests Created 6 years, 1 month 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 "content/renderer/pepper/message_channel.h" 5 #include "content/renderer/pepper/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"
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 } 180 }
181 181
182 MessageChannel::MessageChannel(PepperPluginInstanceImpl* instance) 182 MessageChannel::MessageChannel(PepperPluginInstanceImpl* instance)
183 : gin::NamedPropertyInterceptor(instance->GetIsolate(), this), 183 : gin::NamedPropertyInterceptor(instance->GetIsolate(), this),
184 instance_(instance), 184 instance_(instance),
185 js_message_queue_state_(WAITING_TO_START), 185 js_message_queue_state_(WAITING_TO_START),
186 blocking_message_depth_(0), 186 blocking_message_depth_(0),
187 plugin_message_queue_state_(WAITING_TO_START), 187 plugin_message_queue_state_(WAITING_TO_START),
188 var_converter_(instance->pp_instance(), 188 var_converter_(instance->pp_instance(),
189 V8VarConverter::kDisallowObjectVars), 189 V8VarConverter::kDisallowObjectVars),
190 var_conversion_weak_ptr_factory_(this),
190 weak_ptr_factory_(this) { 191 weak_ptr_factory_(this) {
191 } 192 }
192 193
193 gin::ObjectTemplateBuilder MessageChannel::GetObjectTemplateBuilder( 194 gin::ObjectTemplateBuilder MessageChannel::GetObjectTemplateBuilder(
194 v8::Isolate* isolate) { 195 v8::Isolate* isolate) {
195 return Wrappable<MessageChannel>::GetObjectTemplateBuilder(isolate) 196 return Wrappable<MessageChannel>::GetObjectTemplateBuilder(isolate)
196 .AddNamedPropertyInterceptor(); 197 .AddNamedPropertyInterceptor();
197 } 198 }
198 199
199 void MessageChannel::BeginBlockOnSyncMessage() { 200 void MessageChannel::BeginBlockOnSyncMessage() {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 NOTREACHED(); 307 NOTREACHED();
307 } 308 }
308 309
309 if (plugin_message_queue_state_ == WAITING_TO_START) { 310 if (plugin_message_queue_state_ == WAITING_TO_START) {
310 try_catch.ThrowException( 311 try_catch.ThrowException(
311 "Attempted to call a synchronous method on a plugin that was not " 312 "Attempted to call a synchronous method on a plugin that was not "
312 "yet loaded."); 313 "yet loaded.");
313 return; 314 return;
314 } 315 }
315 316
316 // If the queue of messages to the plugin is non-empty, we're still waiting on
317 // pending Var conversions. This means at some point in the past, JavaScript
318 // called postMessage (the async one) and passed us something with a browser-
319 // side host (e.g., FileSystem) and we haven't gotten a response from the
320 // browser yet. We can't currently support sending a sync message if the
321 // plugin does this, because it will break the ordering of the messages
322 // arriving at the plugin.
323 // TODO(dmichael): Fix this.
324 // See https://code.google.com/p/chromium/issues/detail?id=367896#c4
325 if (!plugin_message_queue_.empty()) {
326 try_catch.ThrowException(
327 "Failed to convert parameter synchronously, because a prior "
328 "call to postMessage contained a type which required asynchronous "
329 "transfer which has not completed. Not all types are supported yet by "
330 "postMessageAndAwaitResponse. See crbug.com/367896.");
331 return;
332 }
333 ScopedPPVar param = try_catch.FromV8(message_data); 317 ScopedPPVar param = try_catch.FromV8(message_data);
334 if (try_catch.ThrowException()) 318 if (try_catch.ThrowException())
335 return; 319 return;
320 if (!plugin_message_queue_.empty()) {
321 // If the queue of messages to the plugin is non-empty, we're still waiting
322 // on pending Var conversions. This means at some point in the past,
323 // JavaScript called postMessage (the async one) and passed us something
324 // with a browser-side host (e.g., FileSystem) and we haven't gotten a
325 // response from the browser yet. We have to force all the conversions to
326 // happen synchronously so that we can preserve message order.
327
328 // CURRENT STRATEGY:
329 // 1) Always push async conversions to the browser. They'll be guaranteed
330 // to arrive in order.
331 // 2) For blocking messages, after you've queued up the conversion, if
332 // there's anything waiting in the queue, it's irrelevant whether it
333 // is from that sync message or an earlier one. We want to block until
334 // it's complete.
335
336 // TODO/FIXME Force the browser to convert all pending vars here
337 // Mark all messages in the queue completed.
338 // Now all our pending vars have completed synchronously, but the browser
339 // might already have sent us a response for one or more of them, so we
340 // make sure the conversion callbacks don't get invoked.
341 var_conversion_weak_ptr_factory_.InvalidateWeakPtrs();
342 }
336 343
337 ScopedPPVar pp_result; 344 ScopedPPVar pp_result;
338 bool was_handled = instance_->HandleBlockingMessage(param, &pp_result); 345 bool was_handled = instance_->HandleBlockingMessage(param, &pp_result);
339 if (!was_handled) { 346 if (!was_handled) {
340 try_catch.ThrowException( 347 try_catch.ThrowException(
341 "The plugin has not registered a handler for synchronous messages. " 348 "The plugin has not registered a handler for synchronous messages. "
342 "See the documentation for PPB_Messaging::RegisterMessageHandler " 349 "See the documentation for PPB_Messaging::RegisterMessageHandler "
343 "and PPP_MessageHandler."); 350 "and PPP_MessageHandler.");
344 return; 351 return;
345 } 352 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 // Convert the v8 value in to an appropriate PP_Var like Dictionary, 398 // Convert the v8 value in to an appropriate PP_Var like Dictionary,
392 // Array, etc. (We explicitly don't want an "Object" PP_Var, which we don't 399 // Array, etc. (We explicitly don't want an "Object" PP_Var, which we don't
393 // support for Messaging.) 400 // support for Messaging.)
394 // TODO(raymes): Possibly change this to use TryCatch to do the conversion and 401 // TODO(raymes): Possibly change this to use TryCatch to do the conversion and
395 // throw an exception if necessary. 402 // throw an exception if necessary.
396 V8VarConverter::VarResult conversion_result = 403 V8VarConverter::VarResult conversion_result =
397 var_converter_.FromV8Value( 404 var_converter_.FromV8Value(
398 v8_value, 405 v8_value,
399 v8::Isolate::GetCurrent()->GetCurrentContext(), 406 v8::Isolate::GetCurrent()->GetCurrentContext(),
400 base::Bind(&MessageChannel::FromV8ValueComplete, 407 base::Bind(&MessageChannel::FromV8ValueComplete,
401 weak_ptr_factory_.GetWeakPtr(), 408 var_conversion_weak_ptr_factory_.GetWeakPtr(),
402 &plugin_message_queue_.back())); 409 &plugin_message_queue_.back()));
403 if (conversion_result.completed_synchronously) { 410 if (conversion_result.completed_synchronously) {
404 plugin_message_queue_.back().ConversionCompleted( 411 plugin_message_queue_.back().ConversionCompleted(
405 conversion_result.var, 412 conversion_result.var,
406 conversion_result.success); 413 conversion_result.success);
407 } 414 }
408 } 415 }
409 416
410 void MessageChannel::FromV8ValueComplete(VarConversionResult* result_holder, 417 void MessageChannel::FromV8ValueComplete(VarConversionResult* result_holder,
411 const ScopedPPVar& result, 418 const ScopedPPVar& result,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 } 468 }
462 469
463 void MessageChannel::UnregisterSyncMessageStatusObserver() { 470 void MessageChannel::UnregisterSyncMessageStatusObserver() {
464 if (!unregister_observer_callback_.is_null()) { 471 if (!unregister_observer_callback_.is_null()) {
465 unregister_observer_callback_.Run(); 472 unregister_observer_callback_.Run();
466 unregister_observer_callback_.Reset(); 473 unregister_observer_callback_.Reset();
467 } 474 }
468 } 475 }
469 476
470 } // namespace content 477 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/pepper/message_channel.h ('k') | content/renderer/pepper/mock_renderer_ppapi_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698