| OLD | NEW |
| 1 // Copyright (c) 2011 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 "webkit/plugins/ppapi/message_channel.h" | 5 #include "webkit/plugins/ppapi/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" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 39 namespace webkit { | 39 namespace webkit { |
| 40 | 40 |
| 41 namespace ppapi { | 41 namespace ppapi { |
| 42 | 42 |
| 43 namespace { | 43 namespace { |
| 44 | 44 |
| 45 const char kPostMessage[] = "postMessage"; | 45 const char kPostMessage[] = "postMessage"; |
| 46 | 46 |
| 47 // Helper function to get the MessageChannel that is associated with an | 47 // Helper function to get the MessageChannel that is associated with an |
| 48 // NPObject*. | 48 // NPObject*. |
| 49 MessageChannel& ToMessageChannel(NPObject* object) { | 49 MessageChannel* ToMessageChannel(NPObject* object) { |
| 50 return *(static_cast<MessageChannel::MessageChannelNPObject*>(object)-> | 50 return static_cast<MessageChannel::MessageChannelNPObject*>(object)-> |
| 51 message_channel); | 51 message_channel; |
| 52 } |
| 53 |
| 54 NPObject* ToPassThroughObject(NPObject* object) { |
| 55 MessageChannel* channel = ToMessageChannel(object); |
| 56 return channel ? channel->passthrough_object() : NULL; |
| 52 } | 57 } |
| 53 | 58 |
| 54 // Helper function to determine if a given identifier is equal to kPostMessage. | 59 // Helper function to determine if a given identifier is equal to kPostMessage. |
| 55 bool IdentifierIsPostMessage(NPIdentifier identifier) { | 60 bool IdentifierIsPostMessage(NPIdentifier identifier) { |
| 56 return WebBindings::getStringIdentifier(kPostMessage) == identifier; | 61 return WebBindings::getStringIdentifier(kPostMessage) == identifier; |
| 57 } | 62 } |
| 58 | 63 |
| 59 // Converts the given PP_Var to a v8::Value, returning true on success. | 64 // Converts the given PP_Var to a v8::Value, returning true on success. |
| 60 // False means that the given variant is invalid. In this case, |result| will | 65 // False means that the given variant is invalid. In this case, |result| will |
| 61 // be set to an empty handle. | 66 // be set to an empty handle. |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 | 171 |
| 167 bool MessageChannelHasMethod(NPObject* np_obj, NPIdentifier name) { | 172 bool MessageChannelHasMethod(NPObject* np_obj, NPIdentifier name) { |
| 168 if (!np_obj) | 173 if (!np_obj) |
| 169 return false; | 174 return false; |
| 170 | 175 |
| 171 // We only handle a function called postMessage. | 176 // We only handle a function called postMessage. |
| 172 if (IdentifierIsPostMessage(name)) | 177 if (IdentifierIsPostMessage(name)) |
| 173 return true; | 178 return true; |
| 174 | 179 |
| 175 // Other method names we will pass to the passthrough object, if we have one. | 180 // Other method names we will pass to the passthrough object, if we have one. |
| 176 NPObject* passthrough = ToMessageChannel(np_obj).passthrough_object(); | 181 NPObject* passthrough = ToPassThroughObject(np_obj); |
| 177 if (passthrough) | 182 if (passthrough) |
| 178 return WebBindings::hasMethod(NULL, passthrough, name); | 183 return WebBindings::hasMethod(NULL, passthrough, name); |
| 179 return false; | 184 return false; |
| 180 } | 185 } |
| 181 | 186 |
| 182 bool MessageChannelInvoke(NPObject* np_obj, NPIdentifier name, | 187 bool MessageChannelInvoke(NPObject* np_obj, NPIdentifier name, |
| 183 const NPVariant* args, uint32 arg_count, | 188 const NPVariant* args, uint32 arg_count, |
| 184 NPVariant* result) { | 189 NPVariant* result) { |
| 185 if (!np_obj) | 190 if (!np_obj) |
| 186 return false; | 191 return false; |
| 187 | 192 |
| 188 // We only handle a function called postMessage. | 193 // We only handle a function called postMessage. |
| 189 if (IdentifierIsPostMessage(name) && (arg_count == 1)) { | 194 if (IdentifierIsPostMessage(name) && (arg_count == 1)) { |
| 190 MessageChannel& message_channel(ToMessageChannel(np_obj)); | 195 MessageChannel* message_channel = ToMessageChannel(np_obj); |
| 191 PP_Var argument(NPVariantToPPVar(message_channel.instance(), &args[0])); | 196 if (message_channel) { |
| 192 message_channel.PostMessageToNative(argument); | 197 PP_Var argument(NPVariantToPPVar(message_channel->instance(), &args[0])); |
| 193 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(argument); | 198 message_channel->PostMessageToNative(argument); |
| 194 return true; | 199 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(argument); |
| 200 return true; |
| 201 } else { |
| 202 return false; |
| 203 } |
| 195 } | 204 } |
| 196 // Other method calls we will pass to the passthrough object, if we have one. | 205 // Other method calls we will pass to the passthrough object, if we have one. |
| 197 NPObject* passthrough = ToMessageChannel(np_obj).passthrough_object(); | 206 NPObject* passthrough = ToPassThroughObject(np_obj); |
| 198 if (passthrough) { | 207 if (passthrough) { |
| 199 return WebBindings::invoke(NULL, passthrough, name, args, arg_count, | 208 return WebBindings::invoke(NULL, passthrough, name, args, arg_count, |
| 200 result); | 209 result); |
| 201 } | 210 } |
| 202 return false; | 211 return false; |
| 203 } | 212 } |
| 204 | 213 |
| 205 bool MessageChannelInvokeDefault(NPObject* np_obj, | 214 bool MessageChannelInvokeDefault(NPObject* np_obj, |
| 206 const NPVariant* args, | 215 const NPVariant* args, |
| 207 uint32 arg_count, | 216 uint32 arg_count, |
| 208 NPVariant* result) { | 217 NPVariant* result) { |
| 209 if (!np_obj) | 218 if (!np_obj) |
| 210 return false; | 219 return false; |
| 211 | 220 |
| 212 // Invoke on the passthrough object, if we have one. | 221 // Invoke on the passthrough object, if we have one. |
| 213 NPObject* passthrough = ToMessageChannel(np_obj).passthrough_object(); | 222 NPObject* passthrough = ToPassThroughObject(np_obj); |
| 214 if (passthrough) { | 223 if (passthrough) { |
| 215 return WebBindings::invokeDefault(NULL, passthrough, args, arg_count, | 224 return WebBindings::invokeDefault(NULL, passthrough, args, arg_count, |
| 216 result); | 225 result); |
| 217 } | 226 } |
| 218 return false; | 227 return false; |
| 219 } | 228 } |
| 220 | 229 |
| 221 bool MessageChannelHasProperty(NPObject* np_obj, NPIdentifier name) { | 230 bool MessageChannelHasProperty(NPObject* np_obj, NPIdentifier name) { |
| 222 if (!np_obj) | 231 if (!np_obj) |
| 223 return false; | 232 return false; |
| 224 | 233 |
| 225 // Invoke on the passthrough object, if we have one. | 234 // Invoke on the passthrough object, if we have one. |
| 226 NPObject* passthrough = ToMessageChannel(np_obj).passthrough_object(); | 235 NPObject* passthrough = ToPassThroughObject(np_obj); |
| 227 if (passthrough) | 236 if (passthrough) |
| 228 return WebBindings::hasProperty(NULL, passthrough, name); | 237 return WebBindings::hasProperty(NULL, passthrough, name); |
| 229 return false; | 238 return false; |
| 230 } | 239 } |
| 231 | 240 |
| 232 bool MessageChannelGetProperty(NPObject* np_obj, NPIdentifier name, | 241 bool MessageChannelGetProperty(NPObject* np_obj, NPIdentifier name, |
| 233 NPVariant* result) { | 242 NPVariant* result) { |
| 234 if (!np_obj) | 243 if (!np_obj) |
| 235 return false; | 244 return false; |
| 236 | 245 |
| 237 // Don't allow getting the postMessage function. | 246 // Don't allow getting the postMessage function. |
| 238 if (IdentifierIsPostMessage(name)) | 247 if (IdentifierIsPostMessage(name)) |
| 239 return false; | 248 return false; |
| 240 | 249 |
| 241 // Invoke on the passthrough object, if we have one. | 250 // Invoke on the passthrough object, if we have one. |
| 242 NPObject* passthrough = ToMessageChannel(np_obj).passthrough_object(); | 251 NPObject* passthrough = ToPassThroughObject(np_obj); |
| 243 if (passthrough) | 252 if (passthrough) |
| 244 return WebBindings::getProperty(NULL, passthrough, name, result); | 253 return WebBindings::getProperty(NULL, passthrough, name, result); |
| 245 return false; | 254 return false; |
| 246 } | 255 } |
| 247 | 256 |
| 248 bool MessageChannelSetProperty(NPObject* np_obj, NPIdentifier name, | 257 bool MessageChannelSetProperty(NPObject* np_obj, NPIdentifier name, |
| 249 const NPVariant* variant) { | 258 const NPVariant* variant) { |
| 250 if (!np_obj) | 259 if (!np_obj) |
| 251 return false; | 260 return false; |
| 252 | 261 |
| 253 // Don't allow setting the postMessage function. | 262 // Don't allow setting the postMessage function. |
| 254 if (IdentifierIsPostMessage(name)) | 263 if (IdentifierIsPostMessage(name)) |
| 255 return false; | 264 return false; |
| 256 | 265 |
| 257 // Invoke on the passthrough object, if we have one. | 266 // Invoke on the passthrough object, if we have one. |
| 258 NPObject* passthrough = ToMessageChannel(np_obj).passthrough_object(); | 267 NPObject* passthrough = ToPassThroughObject(np_obj); |
| 259 if (passthrough) | 268 if (passthrough) |
| 260 return WebBindings::setProperty(NULL, passthrough, name, variant); | 269 return WebBindings::setProperty(NULL, passthrough, name, variant); |
| 261 return false; | 270 return false; |
| 262 } | 271 } |
| 263 | 272 |
| 264 bool MessageChannelEnumerate(NPObject *np_obj, NPIdentifier **value, | 273 bool MessageChannelEnumerate(NPObject *np_obj, NPIdentifier **value, |
| 265 uint32_t *count) { | 274 uint32_t *count) { |
| 266 if (!np_obj) | 275 if (!np_obj) |
| 267 return false; | 276 return false; |
| 268 | 277 |
| 269 // Invoke on the passthrough object, if we have one, to enumerate its | 278 // Invoke on the passthrough object, if we have one, to enumerate its |
| 270 // properties. | 279 // properties. |
| 271 NPObject* passthrough = ToMessageChannel(np_obj).passthrough_object(); | 280 NPObject* passthrough = ToPassThroughObject(np_obj); |
| 272 if (passthrough) { | 281 if (passthrough) { |
| 273 bool success = WebBindings::enumerate(NULL, passthrough, value, count); | 282 bool success = WebBindings::enumerate(NULL, passthrough, value, count); |
| 274 if (success) { | 283 if (success) { |
| 275 // Add postMessage to the list and return it. | 284 // Add postMessage to the list and return it. |
| 276 if (std::numeric_limits<size_t>::max() / sizeof(NPIdentifier) <= | 285 if (std::numeric_limits<size_t>::max() / sizeof(NPIdentifier) <= |
| 277 (*count + 1)) | 286 (*count + 1)) |
| 278 return false; | 287 return false; |
| 279 NPIdentifier* new_array = static_cast<NPIdentifier*>( | 288 NPIdentifier* new_array = static_cast<NPIdentifier*>( |
| 280 std::malloc(sizeof(NPIdentifier) * (*count + 1))); | 289 std::malloc(sizeof(NPIdentifier) * (*count + 1))); |
| 281 std::memcpy(new_array, *value, sizeof(NPIdentifier)*(*count)); | 290 std::memcpy(new_array, *value, sizeof(NPIdentifier)*(*count)); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 305 &MessageChannelHasProperty, | 314 &MessageChannelHasProperty, |
| 306 &MessageChannelGetProperty, | 315 &MessageChannelGetProperty, |
| 307 &MessageChannelSetProperty, | 316 &MessageChannelSetProperty, |
| 308 NULL, | 317 NULL, |
| 309 &MessageChannelEnumerate, | 318 &MessageChannelEnumerate, |
| 310 }; | 319 }; |
| 311 | 320 |
| 312 } // namespace | 321 } // namespace |
| 313 | 322 |
| 314 // MessageChannel -------------------------------------------------------------- | 323 // MessageChannel -------------------------------------------------------------- |
| 315 MessageChannel::MessageChannelNPObject::MessageChannelNPObject() | 324 MessageChannel::MessageChannelNPObject::MessageChannelNPObject() { |
| 316 : message_channel(NULL) { | |
| 317 } | 325 } |
| 318 | 326 |
| 319 MessageChannel::MessageChannelNPObject::~MessageChannelNPObject() {} | 327 MessageChannel::MessageChannelNPObject::~MessageChannelNPObject() {} |
| 320 | 328 |
| 321 MessageChannel::MessageChannel(PluginInstance* instance) | 329 MessageChannel::MessageChannel(PluginInstance* instance) |
| 322 : instance_(instance), | 330 : instance_(instance), |
| 323 passthrough_object_(NULL), | 331 passthrough_object_(NULL), |
| 324 np_object_(NULL), | 332 np_object_(NULL), |
| 325 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | 333 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
| 326 // Now create an NPObject for receiving calls to postMessage. This sets the | 334 // Now create an NPObject for receiving calls to postMessage. This sets the |
| 327 // reference count to 1. We release it in the destructor. | 335 // reference count to 1. We release it in the destructor. |
| 328 NPObject* obj = WebBindings::createObject(NULL, &message_channel_class); | 336 NPObject* obj = WebBindings::createObject(NULL, &message_channel_class); |
| 329 DCHECK(obj); | 337 DCHECK(obj); |
| 330 np_object_ = static_cast<MessageChannel::MessageChannelNPObject*>(obj); | 338 np_object_ = static_cast<MessageChannel::MessageChannelNPObject*>(obj); |
| 331 np_object_->message_channel = this; | 339 np_object_->message_channel = weak_ptr_factory_.GetWeakPtr(); |
| 332 } | 340 } |
| 333 | 341 |
| 334 void MessageChannel::PostMessageToJavaScript(PP_Var message_data) { | 342 void MessageChannel::PostMessageToJavaScript(PP_Var message_data) { |
| 335 // Serialize the message data. | 343 // Serialize the message data. |
| 336 v8::HandleScope scope; | 344 v8::HandleScope scope; |
| 337 // Because V8 is probably not on the stack for Native->JS calls, we need to | 345 // Because V8 is probably not on the stack for Native->JS calls, we need to |
| 338 // enter the appropriate context for the plugin. | 346 // enter the appropriate context for the plugin. |
| 339 v8::Local<v8::Context> context = | 347 v8::Local<v8::Context> context = |
| 340 instance_->container()->element().document().frame()-> | 348 instance_->container()->element().document().frame()-> |
| 341 mainWorldScriptContext(); | 349 mainWorldScriptContext(); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 // invokes: | 427 // invokes: |
| 420 // SetPassthroughObject(passthrough_object()); | 428 // SetPassthroughObject(passthrough_object()); |
| 421 if (passthrough_object_) | 429 if (passthrough_object_) |
| 422 WebBindings::releaseObject(passthrough_object_); | 430 WebBindings::releaseObject(passthrough_object_); |
| 423 | 431 |
| 424 passthrough_object_ = passthrough; | 432 passthrough_object_ = passthrough; |
| 425 } | 433 } |
| 426 | 434 |
| 427 } // namespace ppapi | 435 } // namespace ppapi |
| 428 } // namespace webkit | 436 } // namespace webkit |
| OLD | NEW |