| 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 |