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 |