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" |
(...skipping 26 matching lines...) Expand all Loading... |
37 using blink::WebDOMEvent; | 37 using blink::WebDOMEvent; |
38 using blink::WebDOMMessageEvent; | 38 using blink::WebDOMMessageEvent; |
39 using blink::WebPluginContainer; | 39 using blink::WebPluginContainer; |
40 using blink::WebSerializedScriptValue; | 40 using blink::WebSerializedScriptValue; |
41 | 41 |
42 namespace content { | 42 namespace content { |
43 | 43 |
44 namespace { | 44 namespace { |
45 | 45 |
46 const char kPostMessage[] = "postMessage"; | 46 const char kPostMessage[] = "postMessage"; |
47 const char kV8ToVarConversionError[] = "Failed to convert a PostMessage " | 47 const char kV8ToVarConversionError[] = |
| 48 "Failed to convert a PostMessage " |
48 "argument from a JavaScript value to a PP_Var. It may have cycles or be of " | 49 "argument from a JavaScript value to a PP_Var. It may have cycles or be of " |
49 "an unsupported type."; | 50 "an unsupported type."; |
50 const char kVarToV8ConversionError[] = "Failed to convert a PostMessage " | 51 const char kVarToV8ConversionError[] = |
| 52 "Failed to convert a PostMessage " |
51 "argument from a PP_Var to a Javascript value. It may have cycles or be of " | 53 "argument from a PP_Var to a Javascript value. It may have cycles or be of " |
52 "an unsupported type."; | 54 "an unsupported type."; |
53 | 55 |
54 // Helper function to get the MessageChannel that is associated with an | 56 // Helper function to get the MessageChannel that is associated with an |
55 // NPObject*. | 57 // NPObject*. |
56 MessageChannel* ToMessageChannel(NPObject* object) { | 58 MessageChannel* ToMessageChannel(NPObject* object) { |
57 return static_cast<MessageChannel::MessageChannelNPObject*>(object)-> | 59 return static_cast<MessageChannel::MessageChannelNPObject*>(object) |
58 message_channel.get(); | 60 ->message_channel.get(); |
59 } | 61 } |
60 | 62 |
61 NPObject* ToPassThroughObject(NPObject* object) { | 63 NPObject* ToPassThroughObject(NPObject* object) { |
62 MessageChannel* channel = ToMessageChannel(object); | 64 MessageChannel* channel = ToMessageChannel(object); |
63 return channel ? channel->passthrough_object() : NULL; | 65 return channel ? channel->passthrough_object() : NULL; |
64 } | 66 } |
65 | 67 |
66 // Helper function to determine if a given identifier is equal to kPostMessage. | 68 // Helper function to determine if a given identifier is equal to kPostMessage. |
67 bool IdentifierIsPostMessage(NPIdentifier identifier) { | 69 bool IdentifierIsPostMessage(NPIdentifier identifier) { |
68 return WebBindings::getStringIdentifier(kPostMessage) == identifier; | 70 return WebBindings::getStringIdentifier(kPostMessage) == identifier; |
(...skipping 13 matching lines...) Expand all Loading... |
82 case PP_VARTYPE_STRING: { | 84 case PP_VARTYPE_STRING: { |
83 StringVar* string = StringVar::FromPPVar(var); | 85 StringVar* string = StringVar::FromPPVar(var); |
84 if (!string) | 86 if (!string) |
85 return PP_MakeUndefined(); | 87 return PP_MakeUndefined(); |
86 return StringVar::StringToPPVar(string->value()); | 88 return StringVar::StringToPPVar(string->value()); |
87 } | 89 } |
88 case PP_VARTYPE_ARRAY_BUFFER: { | 90 case PP_VARTYPE_ARRAY_BUFFER: { |
89 ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(var); | 91 ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(var); |
90 if (!buffer) | 92 if (!buffer) |
91 return PP_MakeUndefined(); | 93 return PP_MakeUndefined(); |
92 PP_Var new_buffer_var = PpapiGlobals::Get()->GetVarTracker()-> | 94 PP_Var new_buffer_var = |
93 MakeArrayBufferPPVar(buffer->ByteLength()); | 95 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( |
| 96 buffer->ByteLength()); |
94 DCHECK(new_buffer_var.type == PP_VARTYPE_ARRAY_BUFFER); | 97 DCHECK(new_buffer_var.type == PP_VARTYPE_ARRAY_BUFFER); |
95 if (new_buffer_var.type != PP_VARTYPE_ARRAY_BUFFER) | 98 if (new_buffer_var.type != PP_VARTYPE_ARRAY_BUFFER) |
96 return PP_MakeUndefined(); | 99 return PP_MakeUndefined(); |
97 ArrayBufferVar* new_buffer = ArrayBufferVar::FromPPVar(new_buffer_var); | 100 ArrayBufferVar* new_buffer = ArrayBufferVar::FromPPVar(new_buffer_var); |
98 DCHECK(new_buffer); | 101 DCHECK(new_buffer); |
99 if (!new_buffer) | 102 if (!new_buffer) |
100 return PP_MakeUndefined(); | 103 return PP_MakeUndefined(); |
101 memcpy(new_buffer->Map(), buffer->Map(), buffer->ByteLength()); | 104 memcpy(new_buffer->Map(), buffer->Map(), buffer->ByteLength()); |
102 return new_buffer_var; | 105 return new_buffer_var; |
103 } | 106 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 if (IdentifierIsPostMessage(name)) | 141 if (IdentifierIsPostMessage(name)) |
139 return true; | 142 return true; |
140 | 143 |
141 // Other method names we will pass to the passthrough object, if we have one. | 144 // Other method names we will pass to the passthrough object, if we have one. |
142 NPObject* passthrough = ToPassThroughObject(np_obj); | 145 NPObject* passthrough = ToPassThroughObject(np_obj); |
143 if (passthrough) | 146 if (passthrough) |
144 return WebBindings::hasMethod(NULL, passthrough, name); | 147 return WebBindings::hasMethod(NULL, passthrough, name); |
145 return false; | 148 return false; |
146 } | 149 } |
147 | 150 |
148 bool MessageChannelInvoke(NPObject* np_obj, NPIdentifier name, | 151 bool MessageChannelInvoke(NPObject* np_obj, |
149 const NPVariant* args, uint32 arg_count, | 152 NPIdentifier name, |
| 153 const NPVariant* args, |
| 154 uint32 arg_count, |
150 NPVariant* result) { | 155 NPVariant* result) { |
151 if (!np_obj) | 156 if (!np_obj) |
152 return false; | 157 return false; |
153 | 158 |
154 // We only handle a function called postMessage. | 159 // We only handle a function called postMessage. |
155 if (IdentifierIsPostMessage(name) && (arg_count == 1)) { | 160 if (IdentifierIsPostMessage(name) && (arg_count == 1)) { |
156 MessageChannel* message_channel = ToMessageChannel(np_obj); | 161 MessageChannel* message_channel = ToMessageChannel(np_obj); |
157 if (message_channel) { | 162 if (message_channel) { |
158 message_channel->NPVariantToPPVar(&args[0]); | 163 message_channel->NPVariantToPPVar(&args[0]); |
159 return true; | 164 return true; |
160 } else { | 165 } else { |
161 return false; | 166 return false; |
162 } | 167 } |
163 } | 168 } |
164 // Other method calls we will pass to the passthrough object, if we have one. | 169 // Other method calls we will pass to the passthrough object, if we have one. |
165 NPObject* passthrough = ToPassThroughObject(np_obj); | 170 NPObject* passthrough = ToPassThroughObject(np_obj); |
166 if (passthrough) { | 171 if (passthrough) { |
167 return WebBindings::invoke(NULL, passthrough, name, args, arg_count, | 172 return WebBindings::invoke( |
168 result); | 173 NULL, passthrough, name, args, arg_count, result); |
169 } | 174 } |
170 return false; | 175 return false; |
171 } | 176 } |
172 | 177 |
173 bool MessageChannelInvokeDefault(NPObject* np_obj, | 178 bool MessageChannelInvokeDefault(NPObject* np_obj, |
174 const NPVariant* args, | 179 const NPVariant* args, |
175 uint32 arg_count, | 180 uint32 arg_count, |
176 NPVariant* result) { | 181 NPVariant* result) { |
177 if (!np_obj) | 182 if (!np_obj) |
178 return false; | 183 return false; |
179 | 184 |
180 // Invoke on the passthrough object, if we have one. | 185 // Invoke on the passthrough object, if we have one. |
181 NPObject* passthrough = ToPassThroughObject(np_obj); | 186 NPObject* passthrough = ToPassThroughObject(np_obj); |
182 if (passthrough) { | 187 if (passthrough) { |
183 return WebBindings::invokeDefault(NULL, passthrough, args, arg_count, | 188 return WebBindings::invokeDefault( |
184 result); | 189 NULL, passthrough, args, arg_count, result); |
185 } | 190 } |
186 return false; | 191 return false; |
187 } | 192 } |
188 | 193 |
189 bool MessageChannelHasProperty(NPObject* np_obj, NPIdentifier name) { | 194 bool MessageChannelHasProperty(NPObject* np_obj, NPIdentifier name) { |
190 if (!np_obj) | 195 if (!np_obj) |
191 return false; | 196 return false; |
192 | 197 |
193 MessageChannel* message_channel = ToMessageChannel(np_obj); | 198 MessageChannel* message_channel = ToMessageChannel(np_obj); |
194 if (message_channel) { | 199 if (message_channel) { |
195 if (message_channel->GetReadOnlyProperty(name, NULL)) | 200 if (message_channel->GetReadOnlyProperty(name, NULL)) |
196 return true; | 201 return true; |
197 } | 202 } |
198 | 203 |
199 // Invoke on the passthrough object, if we have one. | 204 // Invoke on the passthrough object, if we have one. |
200 NPObject* passthrough = ToPassThroughObject(np_obj); | 205 NPObject* passthrough = ToPassThroughObject(np_obj); |
201 if (passthrough) | 206 if (passthrough) |
202 return WebBindings::hasProperty(NULL, passthrough, name); | 207 return WebBindings::hasProperty(NULL, passthrough, name); |
203 return false; | 208 return false; |
204 } | 209 } |
205 | 210 |
206 bool MessageChannelGetProperty(NPObject* np_obj, NPIdentifier name, | 211 bool MessageChannelGetProperty(NPObject* np_obj, |
| 212 NPIdentifier name, |
207 NPVariant* result) { | 213 NPVariant* result) { |
208 if (!np_obj) | 214 if (!np_obj) |
209 return false; | 215 return false; |
210 | 216 |
211 // Don't allow getting the postMessage function. | 217 // Don't allow getting the postMessage function. |
212 if (IdentifierIsPostMessage(name)) | 218 if (IdentifierIsPostMessage(name)) |
213 return false; | 219 return false; |
214 | 220 |
215 MessageChannel* message_channel = ToMessageChannel(np_obj); | 221 MessageChannel* message_channel = ToMessageChannel(np_obj); |
216 if (message_channel) { | 222 if (message_channel) { |
217 if (message_channel->GetReadOnlyProperty(name, result)) | 223 if (message_channel->GetReadOnlyProperty(name, result)) |
218 return true; | 224 return true; |
219 } | 225 } |
220 | 226 |
221 // Invoke on the passthrough object, if we have one. | 227 // Invoke on the passthrough object, if we have one. |
222 NPObject* passthrough = ToPassThroughObject(np_obj); | 228 NPObject* passthrough = ToPassThroughObject(np_obj); |
223 if (passthrough) | 229 if (passthrough) |
224 return WebBindings::getProperty(NULL, passthrough, name, result); | 230 return WebBindings::getProperty(NULL, passthrough, name, result); |
225 return false; | 231 return false; |
226 } | 232 } |
227 | 233 |
228 bool MessageChannelSetProperty(NPObject* np_obj, NPIdentifier name, | 234 bool MessageChannelSetProperty(NPObject* np_obj, |
| 235 NPIdentifier name, |
229 const NPVariant* variant) { | 236 const NPVariant* variant) { |
230 if (!np_obj) | 237 if (!np_obj) |
231 return false; | 238 return false; |
232 | 239 |
233 // Don't allow setting the postMessage function. | 240 // Don't allow setting the postMessage function. |
234 if (IdentifierIsPostMessage(name)) | 241 if (IdentifierIsPostMessage(name)) |
235 return false; | 242 return false; |
236 | 243 |
237 // Invoke on the passthrough object, if we have one. | 244 // Invoke on the passthrough object, if we have one. |
238 NPObject* passthrough = ToPassThroughObject(np_obj); | 245 NPObject* passthrough = ToPassThroughObject(np_obj); |
239 if (passthrough) | 246 if (passthrough) |
240 return WebBindings::setProperty(NULL, passthrough, name, variant); | 247 return WebBindings::setProperty(NULL, passthrough, name, variant); |
241 return false; | 248 return false; |
242 } | 249 } |
243 | 250 |
244 bool MessageChannelEnumerate(NPObject *np_obj, NPIdentifier **value, | 251 bool MessageChannelEnumerate(NPObject* np_obj, |
245 uint32_t *count) { | 252 NPIdentifier** value, |
| 253 uint32_t* count) { |
246 if (!np_obj) | 254 if (!np_obj) |
247 return false; | 255 return false; |
248 | 256 |
249 // Invoke on the passthrough object, if we have one, to enumerate its | 257 // Invoke on the passthrough object, if we have one, to enumerate its |
250 // properties. | 258 // properties. |
251 NPObject* passthrough = ToPassThroughObject(np_obj); | 259 NPObject* passthrough = ToPassThroughObject(np_obj); |
252 if (passthrough) { | 260 if (passthrough) { |
253 bool success = WebBindings::enumerate(NULL, passthrough, value, count); | 261 bool success = WebBindings::enumerate(NULL, passthrough, value, count); |
254 if (success) { | 262 if (success) { |
255 // Add postMessage to the list and return it. | 263 // Add postMessage to the list and return it. |
256 if (std::numeric_limits<size_t>::max() / sizeof(NPIdentifier) <= | 264 if (std::numeric_limits<size_t>::max() / sizeof(NPIdentifier) <= |
257 static_cast<size_t>(*count) + 1) // Else, "always false" x64 warning. | 265 static_cast<size_t>(*count) + 1) // Else, "always false" x64 warning. |
258 return false; | 266 return false; |
259 NPIdentifier* new_array = static_cast<NPIdentifier*>( | 267 NPIdentifier* new_array = static_cast<NPIdentifier*>( |
260 std::malloc(sizeof(NPIdentifier) * (*count + 1))); | 268 std::malloc(sizeof(NPIdentifier) * (*count + 1))); |
261 std::memcpy(new_array, *value, sizeof(NPIdentifier)*(*count)); | 269 std::memcpy(new_array, *value, sizeof(NPIdentifier) * (*count)); |
262 new_array[*count] = WebBindings::getStringIdentifier(kPostMessage); | 270 new_array[*count] = WebBindings::getStringIdentifier(kPostMessage); |
263 std::free(*value); | 271 std::free(*value); |
264 *value = new_array; | 272 *value = new_array; |
265 ++(*count); | 273 ++(*count); |
266 return true; | 274 return true; |
267 } | 275 } |
268 } | 276 } |
269 | 277 |
270 // Otherwise, build an array that includes only postMessage. | 278 // Otherwise, build an array that includes only postMessage. |
271 *value = static_cast<NPIdentifier*>(malloc(sizeof(NPIdentifier))); | 279 *value = static_cast<NPIdentifier*>(malloc(sizeof(NPIdentifier))); |
272 (*value)[0] = WebBindings::getStringIdentifier(kPostMessage); | 280 (*value)[0] = WebBindings::getStringIdentifier(kPostMessage); |
273 *count = 1; | 281 *count = 1; |
274 return true; | 282 return true; |
275 } | 283 } |
276 | 284 |
277 NPClass message_channel_class = { | 285 NPClass message_channel_class = { |
278 NP_CLASS_STRUCT_VERSION, | 286 NP_CLASS_STRUCT_VERSION, &MessageChannelAllocate, |
279 &MessageChannelAllocate, | 287 &MessageChannelDeallocate, NULL, |
280 &MessageChannelDeallocate, | 288 &MessageChannelHasMethod, &MessageChannelInvoke, |
281 NULL, | 289 &MessageChannelInvokeDefault, &MessageChannelHasProperty, |
282 &MessageChannelHasMethod, | 290 &MessageChannelGetProperty, &MessageChannelSetProperty, |
283 &MessageChannelInvoke, | 291 NULL, &MessageChannelEnumerate, }; |
284 &MessageChannelInvokeDefault, | |
285 &MessageChannelHasProperty, | |
286 &MessageChannelGetProperty, | |
287 &MessageChannelSetProperty, | |
288 NULL, | |
289 &MessageChannelEnumerate, | |
290 }; | |
291 | 292 |
292 } // namespace | 293 } // namespace |
293 | 294 |
294 // MessageChannel -------------------------------------------------------------- | 295 // MessageChannel -------------------------------------------------------------- |
295 struct MessageChannel::VarConversionResult { | 296 struct MessageChannel::VarConversionResult { |
296 VarConversionResult(const ppapi::ScopedPPVar& r, bool s) | 297 VarConversionResult(const ppapi::ScopedPPVar& r, bool s) |
297 : result(r), | 298 : result(r), success(s), conversion_completed(true) {} |
298 success(s), | 299 VarConversionResult() : success(false), conversion_completed(false) {} |
299 conversion_completed(true) {} | |
300 VarConversionResult() | |
301 : success(false), | |
302 conversion_completed(false) {} | |
303 ppapi::ScopedPPVar result; | 300 ppapi::ScopedPPVar result; |
304 bool success; | 301 bool success; |
305 bool conversion_completed; | 302 bool conversion_completed; |
306 }; | 303 }; |
307 | 304 |
308 MessageChannel::MessageChannelNPObject::MessageChannelNPObject() { | 305 MessageChannel::MessageChannelNPObject::MessageChannelNPObject() {} |
309 } | |
310 | 306 |
311 MessageChannel::MessageChannelNPObject::~MessageChannelNPObject() {} | 307 MessageChannel::MessageChannelNPObject::~MessageChannelNPObject() {} |
312 | 308 |
313 MessageChannel::MessageChannel(PepperPluginInstanceImpl* instance) | 309 MessageChannel::MessageChannel(PepperPluginInstanceImpl* instance) |
314 : instance_(instance), | 310 : instance_(instance), |
315 passthrough_object_(NULL), | 311 passthrough_object_(NULL), |
316 np_object_(NULL), | 312 np_object_(NULL), |
317 early_message_queue_state_(QUEUE_MESSAGES), | 313 early_message_queue_state_(QUEUE_MESSAGES), |
318 weak_ptr_factory_(this) { | 314 weak_ptr_factory_(this) { |
319 // Now create an NPObject for receiving calls to postMessage. This sets the | 315 // Now create an NPObject for receiving calls to postMessage. This sets the |
320 // reference count to 1. We release it in the destructor. | 316 // reference count to 1. We release it in the destructor. |
321 NPObject* obj = WebBindings::createObject(instance_->instanceNPP(), | 317 NPObject* obj = WebBindings::createObject(instance_->instanceNPP(), |
322 &message_channel_class); | 318 &message_channel_class); |
323 DCHECK(obj); | 319 DCHECK(obj); |
324 np_object_ = static_cast<MessageChannel::MessageChannelNPObject*>(obj); | 320 np_object_ = static_cast<MessageChannel::MessageChannelNPObject*>(obj); |
325 np_object_->message_channel = weak_ptr_factory_.GetWeakPtr(); | 321 np_object_->message_channel = weak_ptr_factory_.GetWeakPtr(); |
326 } | 322 } |
327 | 323 |
328 void MessageChannel::NPVariantToPPVar(const NPVariant* variant) { | 324 void MessageChannel::NPVariantToPPVar(const NPVariant* variant) { |
329 converted_var_queue_.push_back(VarConversionResult()); | 325 converted_var_queue_.push_back(VarConversionResult()); |
330 std::list<VarConversionResult>::iterator result_iterator = | 326 std::list<VarConversionResult>::iterator result_iterator = |
331 --converted_var_queue_.end(); | 327 --converted_var_queue_.end(); |
332 switch (variant->type) { | 328 switch (variant->type) { |
333 case NPVariantType_Void: | 329 case NPVariantType_Void: |
334 NPVariantToPPVarComplete(result_iterator, | 330 NPVariantToPPVarComplete( |
335 ppapi::ScopedPPVar(PP_MakeUndefined()), true); | 331 result_iterator, ppapi::ScopedPPVar(PP_MakeUndefined()), true); |
336 return; | 332 return; |
337 case NPVariantType_Null: | 333 case NPVariantType_Null: |
338 NPVariantToPPVarComplete(result_iterator, | 334 NPVariantToPPVarComplete( |
339 ppapi::ScopedPPVar(PP_MakeNull()), true); | 335 result_iterator, ppapi::ScopedPPVar(PP_MakeNull()), true); |
340 return; | 336 return; |
341 case NPVariantType_Bool: | 337 case NPVariantType_Bool: |
342 NPVariantToPPVarComplete(result_iterator, | 338 NPVariantToPPVarComplete(result_iterator, |
343 ppapi::ScopedPPVar( | 339 ppapi::ScopedPPVar(PP_MakeBool(PP_FromBool( |
344 PP_MakeBool(PP_FromBool(NPVARIANT_TO_BOOLEAN(*variant)))), | 340 NPVARIANT_TO_BOOLEAN(*variant)))), |
345 true); | 341 true); |
346 return; | 342 return; |
347 case NPVariantType_Int32: | 343 case NPVariantType_Int32: |
348 NPVariantToPPVarComplete(result_iterator, | 344 NPVariantToPPVarComplete( |
349 ppapi::ScopedPPVar( | 345 result_iterator, |
350 PP_MakeInt32(NPVARIANT_TO_INT32(*variant))), | 346 ppapi::ScopedPPVar(PP_MakeInt32(NPVARIANT_TO_INT32(*variant))), |
351 true); | 347 true); |
352 return; | 348 return; |
353 case NPVariantType_Double: | 349 case NPVariantType_Double: |
354 NPVariantToPPVarComplete(result_iterator, | 350 NPVariantToPPVarComplete( |
355 ppapi::ScopedPPVar( | 351 result_iterator, |
356 PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant))), | 352 ppapi::ScopedPPVar(PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant))), |
357 true); | 353 true); |
358 return; | 354 return; |
359 case NPVariantType_String: | 355 case NPVariantType_String: |
360 NPVariantToPPVarComplete(result_iterator, | 356 NPVariantToPPVarComplete( |
| 357 result_iterator, |
361 ppapi::ScopedPPVar(ppapi::ScopedPPVar::PassRef(), | 358 ppapi::ScopedPPVar(ppapi::ScopedPPVar::PassRef(), |
362 StringVar::StringToPPVar( | 359 StringVar::StringToPPVar( |
363 NPVARIANT_TO_STRING(*variant).UTF8Characters, | 360 NPVARIANT_TO_STRING(*variant).UTF8Characters, |
364 NPVARIANT_TO_STRING(*variant).UTF8Length)), | 361 NPVARIANT_TO_STRING(*variant).UTF8Length)), |
365 true); | 362 true); |
366 return; | 363 return; |
367 case NPVariantType_Object: { | 364 case NPVariantType_Object: { |
368 // Calling WebBindings::toV8Value creates a wrapper around NPVariant so it | 365 // Calling WebBindings::toV8Value creates a wrapper around NPVariant so it |
369 // shouldn't result in a deep copy. | 366 // shouldn't result in a deep copy. |
370 v8::Handle<v8::Value> v8_value = WebBindings::toV8Value(variant); | 367 v8::Handle<v8::Value> v8_value = WebBindings::toV8Value(variant); |
371 V8VarConverter(instance_->pp_instance()).FromV8Value( | 368 V8VarConverter(instance_->pp_instance()) |
372 v8_value, v8::Isolate::GetCurrent()->GetCurrentContext(), | 369 .FromV8Value(v8_value, |
373 base::Bind(&MessageChannel::NPVariantToPPVarComplete, | 370 v8::Isolate::GetCurrent()->GetCurrentContext(), |
374 weak_ptr_factory_.GetWeakPtr(), result_iterator)); | 371 base::Bind(&MessageChannel::NPVariantToPPVarComplete, |
| 372 weak_ptr_factory_.GetWeakPtr(), |
| 373 result_iterator)); |
375 return; | 374 return; |
376 } | 375 } |
377 } | 376 } |
378 NPVariantToPPVarComplete(result_iterator, | 377 NPVariantToPPVarComplete( |
379 ppapi::ScopedPPVar(PP_MakeUndefined()), false); | 378 result_iterator, ppapi::ScopedPPVar(PP_MakeUndefined()), false); |
380 } | 379 } |
381 | 380 |
382 void MessageChannel::PostMessageToJavaScript(PP_Var message_data) { | 381 void MessageChannel::PostMessageToJavaScript(PP_Var message_data) { |
383 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 382 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
384 | 383 |
385 // Because V8 is probably not on the stack for Native->JS calls, we need to | 384 // Because V8 is probably not on the stack for Native->JS calls, we need to |
386 // enter the appropriate context for the plugin. | 385 // enter the appropriate context for the plugin. |
387 WebPluginContainer* container = instance_->container(); | 386 WebPluginContainer* container = instance_->container(); |
388 // It's possible that container() is NULL if the plugin has been removed from | 387 // It's possible that container() is NULL if the plugin has been removed from |
389 // the DOM (but the PluginInstance is not destroyed yet). | 388 // the DOM (but the PluginInstance is not destroyed yet). |
390 if (!container) | 389 if (!container) |
391 return; | 390 return; |
392 | 391 |
393 v8::Local<v8::Context> context = | 392 v8::Local<v8::Context> context = |
394 container->element().document().frame()->mainWorldScriptContext(); | 393 container->element().document().frame()->mainWorldScriptContext(); |
395 // If the page is being destroyed, the context may be empty. | 394 // If the page is being destroyed, the context may be empty. |
396 if (context.IsEmpty()) | 395 if (context.IsEmpty()) |
397 return; | 396 return; |
398 v8::Context::Scope context_scope(context); | 397 v8::Context::Scope context_scope(context); |
399 | 398 |
400 v8::Handle<v8::Value> v8_val; | 399 v8::Handle<v8::Value> v8_val; |
401 if (!V8VarConverter(instance_->pp_instance()).ToV8Value( | 400 if (!V8VarConverter(instance_->pp_instance()) |
402 message_data, context, &v8_val)) { | 401 .ToV8Value(message_data, context, &v8_val)) { |
403 PpapiGlobals::Get()->LogWithSource(instance_->pp_instance(), | 402 PpapiGlobals::Get()->LogWithSource(instance_->pp_instance(), |
404 PP_LOGLEVEL_ERROR, std::string(), kVarToV8ConversionError); | 403 PP_LOGLEVEL_ERROR, |
| 404 std::string(), |
| 405 kVarToV8ConversionError); |
405 return; | 406 return; |
406 } | 407 } |
407 | 408 |
408 WebSerializedScriptValue serialized_val = | 409 WebSerializedScriptValue serialized_val = |
409 WebSerializedScriptValue::serialize(v8_val); | 410 WebSerializedScriptValue::serialize(v8_val); |
410 | 411 |
411 if (instance_->module()->IsProxied()) { | 412 if (instance_->module()->IsProxied()) { |
412 if (early_message_queue_state_ != SEND_DIRECTLY) { | 413 if (early_message_queue_state_ != SEND_DIRECTLY) { |
413 // We can't just PostTask here; the messages would arrive out of | 414 // We can't just PostTask here; the messages would arrive out of |
414 // order. Instead, we queue them up until we're ready to post | 415 // order. Instead, we queue them up until we're ready to post |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 const std::list<VarConversionResult>::iterator& result_iterator, | 452 const std::list<VarConversionResult>::iterator& result_iterator, |
452 const ppapi::ScopedPPVar& result, | 453 const ppapi::ScopedPPVar& result, |
453 bool success) { | 454 bool success) { |
454 *result_iterator = VarConversionResult(result, success); | 455 *result_iterator = VarConversionResult(result, success); |
455 std::list<VarConversionResult>::iterator it = converted_var_queue_.begin(); | 456 std::list<VarConversionResult>::iterator it = converted_var_queue_.begin(); |
456 while (it != converted_var_queue_.end() && it->conversion_completed) { | 457 while (it != converted_var_queue_.end() && it->conversion_completed) { |
457 if (it->success) { | 458 if (it->success) { |
458 PostMessageToNative(it->result.get()); | 459 PostMessageToNative(it->result.get()); |
459 } else { | 460 } else { |
460 PpapiGlobals::Get()->LogWithSource(instance()->pp_instance(), | 461 PpapiGlobals::Get()->LogWithSource(instance()->pp_instance(), |
461 PP_LOGLEVEL_ERROR, std::string(), kV8ToVarConversionError); | 462 PP_LOGLEVEL_ERROR, |
| 463 std::string(), |
| 464 kV8ToVarConversionError); |
462 } | 465 } |
463 | 466 |
464 converted_var_queue_.erase(it++); | 467 converted_var_queue_.erase(it++); |
465 } | 468 } |
466 } | 469 } |
467 | 470 |
468 void MessageChannel::DrainEarlyMessageQueue() { | 471 void MessageChannel::DrainEarlyMessageQueue() { |
469 // Take a reference on the PluginInstance. This is because JavaScript code | 472 // Take a reference on the PluginInstance. This is because JavaScript code |
470 // may delete the plugin, which would destroy the PluginInstance and its | 473 // may delete the plugin, which would destroy the PluginInstance and its |
471 // corresponding MessageChannel. | 474 // corresponding MessageChannel. |
(...skipping 18 matching lines...) Expand all Loading... |
490 | 493 |
491 WebPluginContainer* container = instance_->container(); | 494 WebPluginContainer* container = instance_->container(); |
492 // It's possible that container() is NULL if the plugin has been removed from | 495 // It's possible that container() is NULL if the plugin has been removed from |
493 // the DOM (but the PluginInstance is not destroyed yet). | 496 // the DOM (but the PluginInstance is not destroyed yet). |
494 if (!container) | 497 if (!container) |
495 return; | 498 return; |
496 | 499 |
497 WebDOMEvent event = | 500 WebDOMEvent event = |
498 container->element().document().createEvent("MessageEvent"); | 501 container->element().document().createEvent("MessageEvent"); |
499 WebDOMMessageEvent msg_event = event.to<WebDOMMessageEvent>(); | 502 WebDOMMessageEvent msg_event = event.to<WebDOMMessageEvent>(); |
500 msg_event.initMessageEvent("message", // type | 503 msg_event.initMessageEvent("message", // type |
501 false, // canBubble | 504 false, // canBubble |
502 false, // cancelable | 505 false, // cancelable |
503 message_data, // data | 506 message_data, // data |
504 "", // origin [*] | 507 "", // origin [*] |
505 NULL, // source [*] | 508 NULL, // source [*] |
506 ""); // lastEventId | 509 ""); // lastEventId |
507 // [*] Note that the |origin| is only specified for cross-document and server- | 510 // [*] Note that the |origin| is only specified for cross-document and server- |
508 // sent messages, while |source| is only specified for cross-document | 511 // sent messages, while |source| is only specified for cross-document |
509 // messages: | 512 // messages: |
510 // http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html | 513 // http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html |
511 // This currently behaves like Web Workers. On Firefox, Chrome, and Safari | 514 // This currently behaves like Web Workers. On Firefox, Chrome, and Safari |
512 // at least, postMessage on Workers does not provide the origin or source. | 515 // at least, postMessage on Workers does not provide the origin or source. |
513 // TODO(dmichael): Add origin if we change to a more iframe-like origin | 516 // TODO(dmichael): Add origin if we change to a more iframe-like origin |
514 // policy (see crbug.com/81537) | 517 // policy (see crbug.com/81537) |
515 | 518 |
516 container->element().dispatchEvent(msg_event); | 519 container->element().dispatchEvent(msg_event); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 // incoming passthrough object first, so that we behave correctly if anyone | 557 // incoming passthrough object first, so that we behave correctly if anyone |
555 // invokes: | 558 // invokes: |
556 // SetPassthroughObject(passthrough_object()); | 559 // SetPassthroughObject(passthrough_object()); |
557 if (passthrough_object_) | 560 if (passthrough_object_) |
558 WebBindings::releaseObject(passthrough_object_); | 561 WebBindings::releaseObject(passthrough_object_); |
559 | 562 |
560 passthrough_object_ = passthrough; | 563 passthrough_object_ = passthrough; |
561 } | 564 } |
562 | 565 |
563 bool MessageChannel::GetReadOnlyProperty(NPIdentifier key, | 566 bool MessageChannel::GetReadOnlyProperty(NPIdentifier key, |
564 NPVariant *value) const { | 567 NPVariant* value) const { |
565 std::map<NPIdentifier, ppapi::ScopedPPVar>::const_iterator it = | 568 std::map<NPIdentifier, ppapi::ScopedPPVar>::const_iterator it = |
566 internal_properties_.find(key); | 569 internal_properties_.find(key); |
567 if (it != internal_properties_.end()) { | 570 if (it != internal_properties_.end()) { |
568 if (value) | 571 if (value) |
569 return PPVarToNPVariant(it->second.get(), value); | 572 return PPVarToNPVariant(it->second.get(), value); |
570 return true; | 573 return true; |
571 } | 574 } |
572 return false; | 575 return false; |
573 } | 576 } |
574 | 577 |
575 void MessageChannel::SetReadOnlyProperty(PP_Var key, PP_Var value) { | 578 void MessageChannel::SetReadOnlyProperty(PP_Var key, PP_Var value) { |
576 internal_properties_[PPVarToNPIdentifier(key)] = ppapi::ScopedPPVar(value); | 579 internal_properties_[PPVarToNPIdentifier(key)] = ppapi::ScopedPPVar(value); |
577 } | 580 } |
578 | 581 |
579 } // namespace content | 582 } // namespace content |
OLD | NEW |