| OLD | NEW |
| 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" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
| 13 #include "content/renderer/pepper/host_array_buffer_var.h" | 13 #include "content/renderer/pepper/host_array_buffer_var.h" |
| 14 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" | 14 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" |
| 15 #include "content/renderer/pepper/pepper_try_catch.h" | 15 #include "content/renderer/pepper/pepper_try_catch.h" |
| 16 #include "content/renderer/pepper/plugin_module.h" | 16 #include "content/renderer/pepper/plugin_module.h" |
| 17 #include "content/renderer/pepper/plugin_object.h" | 17 #include "content/renderer/pepper/plugin_object.h" |
| 18 #include "content/renderer/pepper/v8_var_converter.h" | |
| 19 #include "gin/arguments.h" | 18 #include "gin/arguments.h" |
| 20 #include "gin/converter.h" | 19 #include "gin/converter.h" |
| 21 #include "gin/function_template.h" | 20 #include "gin/function_template.h" |
| 22 #include "gin/object_template_builder.h" | 21 #include "gin/object_template_builder.h" |
| 23 #include "gin/public/gin_embedders.h" | 22 #include "gin/public/gin_embedders.h" |
| 24 #include "ppapi/shared_impl/ppapi_globals.h" | 23 #include "ppapi/shared_impl/ppapi_globals.h" |
| 25 #include "ppapi/shared_impl/scoped_pp_var.h" | 24 #include "ppapi/shared_impl/scoped_pp_var.h" |
| 26 #include "ppapi/shared_impl/var.h" | 25 #include "ppapi/shared_impl/var.h" |
| 27 #include "ppapi/shared_impl/var_tracker.h" | 26 #include "ppapi/shared_impl/var_tracker.h" |
| 28 #include "third_party/WebKit/public/web/WebBindings.h" | 27 #include "third_party/WebKit/public/web/WebBindings.h" |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 | 114 |
| 116 // Because V8 is probably not on the stack for Native->JS calls, we need to | 115 // Because V8 is probably not on the stack for Native->JS calls, we need to |
| 117 // enter the appropriate context for the plugin. | 116 // enter the appropriate context for the plugin. |
| 118 v8::Local<v8::Context> context = instance_->GetMainWorldContext(); | 117 v8::Local<v8::Context> context = instance_->GetMainWorldContext(); |
| 119 if (context.IsEmpty()) | 118 if (context.IsEmpty()) |
| 120 return; | 119 return; |
| 121 | 120 |
| 122 v8::Context::Scope context_scope(context); | 121 v8::Context::Scope context_scope(context); |
| 123 | 122 |
| 124 v8::Handle<v8::Value> v8_val; | 123 v8::Handle<v8::Value> v8_val; |
| 125 if (!V8VarConverter(instance_->pp_instance()) | 124 if (!var_converter_.ToV8Value(message_data, context, &v8_val)) { |
| 126 .ToV8Value(message_data, context, &v8_val)) { | |
| 127 PpapiGlobals::Get()->LogWithSource(instance_->pp_instance(), | 125 PpapiGlobals::Get()->LogWithSource(instance_->pp_instance(), |
| 128 PP_LOGLEVEL_ERROR, | 126 PP_LOGLEVEL_ERROR, |
| 129 std::string(), | 127 std::string(), |
| 130 kVarToV8ConversionError); | 128 kVarToV8ConversionError); |
| 131 return; | 129 return; |
| 132 } | 130 } |
| 133 | 131 |
| 134 WebSerializedScriptValue serialized_val = | 132 WebSerializedScriptValue serialized_val = |
| 135 WebSerializedScriptValue::serialize(v8_val); | 133 WebSerializedScriptValue::serialize(v8_val); |
| 136 | 134 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 NOTREACHED(); | 178 NOTREACHED(); |
| 181 } | 179 } |
| 182 } | 180 } |
| 183 | 181 |
| 184 MessageChannel::MessageChannel(PepperPluginInstanceImpl* instance) | 182 MessageChannel::MessageChannel(PepperPluginInstanceImpl* instance) |
| 185 : gin::NamedPropertyInterceptor(instance->GetIsolate(), this), | 183 : gin::NamedPropertyInterceptor(instance->GetIsolate(), this), |
| 186 instance_(instance), | 184 instance_(instance), |
| 187 js_message_queue_state_(WAITING_TO_START), | 185 js_message_queue_state_(WAITING_TO_START), |
| 188 blocking_message_depth_(0), | 186 blocking_message_depth_(0), |
| 189 plugin_message_queue_state_(WAITING_TO_START), | 187 plugin_message_queue_state_(WAITING_TO_START), |
| 188 var_converter_(instance->pp_instance(), |
| 189 V8VarConverter::kDisallowObjectVars), |
| 190 weak_ptr_factory_(this) { | 190 weak_ptr_factory_(this) { |
| 191 } | 191 } |
| 192 | 192 |
| 193 gin::ObjectTemplateBuilder MessageChannel::GetObjectTemplateBuilder( | 193 gin::ObjectTemplateBuilder MessageChannel::GetObjectTemplateBuilder( |
| 194 v8::Isolate* isolate) { | 194 v8::Isolate* isolate) { |
| 195 return Wrappable<MessageChannel>::GetObjectTemplateBuilder(isolate) | 195 return Wrappable<MessageChannel>::GetObjectTemplateBuilder(isolate) |
| 196 .AddNamedPropertyInterceptor(); | 196 .AddNamedPropertyInterceptor(); |
| 197 } | 197 } |
| 198 | 198 |
| 199 void MessageChannel::BeginBlockOnSyncMessage() { | 199 void MessageChannel::BeginBlockOnSyncMessage() { |
| 200 js_message_queue_state_ = QUEUE_MESSAGES; | 200 js_message_queue_state_ = QUEUE_MESSAGES; |
| 201 ++blocking_message_depth_; | 201 ++blocking_message_depth_; |
| 202 } | 202 } |
| 203 | 203 |
| 204 void MessageChannel::EndBlockOnSyncMessage() { | 204 void MessageChannel::EndBlockOnSyncMessage() { |
| 205 DCHECK_GT(blocking_message_depth_, 0); | 205 DCHECK_GT(blocking_message_depth_, 0); |
| 206 --blocking_message_depth_; | 206 --blocking_message_depth_; |
| 207 if (!blocking_message_depth_) | 207 if (!blocking_message_depth_) |
| 208 DrainJSMessageQueueSoon(); | 208 DrainJSMessageQueueSoon(); |
| 209 } | 209 } |
| 210 | 210 |
| 211 v8::Local<v8::Value> MessageChannel::GetNamedProperty( | 211 v8::Local<v8::Value> MessageChannel::GetNamedProperty( |
| 212 v8::Isolate* isolate, | 212 v8::Isolate* isolate, |
| 213 const std::string& identifier) { | 213 const std::string& identifier) { |
| 214 if (!instance_) | 214 if (!instance_) |
| 215 return v8::Local<v8::Value>(); | 215 return v8::Local<v8::Value>(); |
| 216 | 216 |
| 217 PepperTryCatchV8 try_catch(instance_, V8VarConverter::kDisallowObjectVars, | 217 PepperTryCatchV8 try_catch(instance_, &var_converter_, isolate); |
| 218 isolate); | |
| 219 if (identifier == kPostMessage) { | 218 if (identifier == kPostMessage) { |
| 220 return gin::CreateFunctionTemplate(isolate, | 219 return gin::CreateFunctionTemplate(isolate, |
| 221 base::Bind(&MessageChannel::PostMessageToNative, | 220 base::Bind(&MessageChannel::PostMessageToNative, |
| 222 weak_ptr_factory_.GetWeakPtr()))->GetFunction(); | 221 weak_ptr_factory_.GetWeakPtr()))->GetFunction(); |
| 223 } else if (identifier == kPostMessageAndAwaitResponse) { | 222 } else if (identifier == kPostMessageAndAwaitResponse) { |
| 224 return gin::CreateFunctionTemplate(isolate, | 223 return gin::CreateFunctionTemplate(isolate, |
| 225 base::Bind(&MessageChannel::PostBlockingMessageToNative, | 224 base::Bind(&MessageChannel::PostBlockingMessageToNative, |
| 226 weak_ptr_factory_.GetWeakPtr()))->GetFunction(); | 225 weak_ptr_factory_.GetWeakPtr()))->GetFunction(); |
| 227 } | 226 } |
| 228 | 227 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 239 if (plugin_object) | 238 if (plugin_object) |
| 240 return plugin_object->GetNamedProperty(isolate, identifier); | 239 return plugin_object->GetNamedProperty(isolate, identifier); |
| 241 return v8::Local<v8::Value>(); | 240 return v8::Local<v8::Value>(); |
| 242 } | 241 } |
| 243 | 242 |
| 244 bool MessageChannel::SetNamedProperty(v8::Isolate* isolate, | 243 bool MessageChannel::SetNamedProperty(v8::Isolate* isolate, |
| 245 const std::string& identifier, | 244 const std::string& identifier, |
| 246 v8::Local<v8::Value> value) { | 245 v8::Local<v8::Value> value) { |
| 247 if (!instance_) | 246 if (!instance_) |
| 248 return false; | 247 return false; |
| 249 PepperTryCatchV8 try_catch(instance_, V8VarConverter::kDisallowObjectVars, | 248 PepperTryCatchV8 try_catch(instance_, &var_converter_, isolate); |
| 250 isolate); | |
| 251 if (identifier == kPostMessage || | 249 if (identifier == kPostMessage || |
| 252 identifier == kPostMessageAndAwaitResponse) { | 250 identifier == kPostMessageAndAwaitResponse) { |
| 253 try_catch.ThrowException("Cannot set properties with the name postMessage" | 251 try_catch.ThrowException("Cannot set properties with the name postMessage" |
| 254 "or postMessageAndAwaitResponse"); | 252 "or postMessageAndAwaitResponse"); |
| 255 return true; | 253 return true; |
| 256 } | 254 } |
| 257 | 255 |
| 258 // TODO(raymes): This is only used by the gTalk plugin which is deprecated. | 256 // TODO(raymes): This is only used by the gTalk plugin which is deprecated. |
| 259 // Remove passthrough of SetProperty calls as soon as it is removed. | 257 // Remove passthrough of SetProperty calls as soon as it is removed. |
| 260 PluginObject* plugin_object = GetPluginObject(isolate); | 258 PluginObject* plugin_object = GetPluginObject(isolate); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 289 NOTREACHED(); | 287 NOTREACHED(); |
| 290 } | 288 } |
| 291 | 289 |
| 292 EnqueuePluginMessage(message_data); | 290 EnqueuePluginMessage(message_data); |
| 293 DrainCompletedPluginMessages(); | 291 DrainCompletedPluginMessages(); |
| 294 } | 292 } |
| 295 | 293 |
| 296 void MessageChannel::PostBlockingMessageToNative(gin::Arguments* args) { | 294 void MessageChannel::PostBlockingMessageToNative(gin::Arguments* args) { |
| 297 if (!instance_) | 295 if (!instance_) |
| 298 return; | 296 return; |
| 299 PepperTryCatchV8 try_catch(instance_, V8VarConverter::kDisallowObjectVars, | 297 PepperTryCatchV8 try_catch(instance_, &var_converter_, args->isolate()); |
| 300 args->isolate()); | |
| 301 if (args->Length() != 1) { | 298 if (args->Length() != 1) { |
| 302 try_catch.ThrowException( | 299 try_catch.ThrowException( |
| 303 "postMessageAndAwaitResponse requires one argument"); | 300 "postMessageAndAwaitResponse requires one argument"); |
| 304 return; | 301 return; |
| 305 } | 302 } |
| 306 | 303 |
| 307 v8::Handle<v8::Value> message_data; | 304 v8::Handle<v8::Value> message_data; |
| 308 if (!args->GetNext(&message_data)) { | 305 if (!args->GetNext(&message_data)) { |
| 309 NOTREACHED(); | 306 NOTREACHED(); |
| 310 } | 307 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 container->element().dispatchEvent(msg_event); | 381 container->element().dispatchEvent(msg_event); |
| 385 } | 382 } |
| 386 | 383 |
| 387 PluginObject* MessageChannel::GetPluginObject(v8::Isolate* isolate) { | 384 PluginObject* MessageChannel::GetPluginObject(v8::Isolate* isolate) { |
| 388 return PluginObject::FromV8Object(isolate, | 385 return PluginObject::FromV8Object(isolate, |
| 389 v8::Local<v8::Object>::New(isolate, passthrough_object_)); | 386 v8::Local<v8::Object>::New(isolate, passthrough_object_)); |
| 390 } | 387 } |
| 391 | 388 |
| 392 void MessageChannel::EnqueuePluginMessage(v8::Handle<v8::Value> v8_value) { | 389 void MessageChannel::EnqueuePluginMessage(v8::Handle<v8::Value> v8_value) { |
| 393 plugin_message_queue_.push_back(VarConversionResult()); | 390 plugin_message_queue_.push_back(VarConversionResult()); |
| 394 // Convert NPVariantType_Object in to an appropriate PP_Var like Dictionary, | 391 // Convert the v8 value in to an appropriate PP_Var like Dictionary, |
| 395 // Array, etc. Note NPVariantToVar would convert to an "Object" PP_Var, | 392 // Array, etc. (We explicitly don't want an "Object" PP_Var, which we don't |
| 396 // which we don't support for Messaging. | 393 // support for Messaging.) |
| 397 // TODO(raymes): Possibly change this to use TryCatch to do the conversion and | 394 // TODO(raymes): Possibly change this to use TryCatch to do the conversion and |
| 398 // throw an exception if necessary. | 395 // throw an exception if necessary. |
| 399 V8VarConverter v8_var_converter(instance_->pp_instance()); | |
| 400 V8VarConverter::VarResult conversion_result = | 396 V8VarConverter::VarResult conversion_result = |
| 401 v8_var_converter.FromV8Value( | 397 var_converter_.FromV8Value( |
| 402 v8_value, | 398 v8_value, |
| 403 v8::Isolate::GetCurrent()->GetCurrentContext(), | 399 v8::Isolate::GetCurrent()->GetCurrentContext(), |
| 404 base::Bind(&MessageChannel::FromV8ValueComplete, | 400 base::Bind(&MessageChannel::FromV8ValueComplete, |
| 405 weak_ptr_factory_.GetWeakPtr(), | 401 weak_ptr_factory_.GetWeakPtr(), |
| 406 &plugin_message_queue_.back())); | 402 &plugin_message_queue_.back())); |
| 407 if (conversion_result.completed_synchronously) { | 403 if (conversion_result.completed_synchronously) { |
| 408 plugin_message_queue_.back().ConversionCompleted( | 404 plugin_message_queue_.back().ConversionCompleted( |
| 409 conversion_result.var, | 405 conversion_result.var, |
| 410 conversion_result.success); | 406 conversion_result.success); |
| 411 } | 407 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 } | 461 } |
| 466 | 462 |
| 467 void MessageChannel::UnregisterSyncMessageStatusObserver() { | 463 void MessageChannel::UnregisterSyncMessageStatusObserver() { |
| 468 if (!unregister_observer_callback_.is_null()) { | 464 if (!unregister_observer_callback_.is_null()) { |
| 469 unregister_observer_callback_.Run(); | 465 unregister_observer_callback_.Run(); |
| 470 unregister_observer_callback_.Reset(); | 466 unregister_observer_callback_.Reset(); |
| 471 } | 467 } |
| 472 } | 468 } |
| 473 | 469 |
| 474 } // namespace content | 470 } // namespace content |
| OLD | NEW |