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 |