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