15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/message_channel.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstdlib> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 13bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/host_array_buffer_var.h" 14bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/npapi_glue.h" 1558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "content/renderer/pepper/pepper_plugin_instance_impl.h" 16bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/plugin_module.h" 17bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/v8_var_converter.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/ppapi_globals.h" 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ppapi/shared_impl/scoped_pp_var.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/var.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/var_tracker.h" 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebBindings.h" 237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h" 247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDOMMessageEvent.h" 257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebElement.h" 267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h" 277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebNode.h" 287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebPluginContainer.h" 297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebSerializedScriptValue.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "v8/include/v8.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::ArrayBufferVar; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::PpapiGlobals; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::StringVar; 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebBindings; 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebElement; 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebDOMEvent; 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebDOMMessageEvent; 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebPluginContainer; 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebSerializedScriptValue; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochnamespace content { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPostMessage[] = "postMessage"; 477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const char kV8ToVarConversionError[] = "Failed to convert a PostMessage " 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "argument from a JavaScript value to a PP_Var. It may have cycles or be of " 497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "an unsupported type."; 507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const char kVarToV8ConversionError[] = "Failed to convert a PostMessage " 517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "argument from a PP_Var to a Javascript value. It may have cycles or be of " 527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "an unsupported type."; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper function to get the MessageChannel that is associated with an 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NPObject*. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageChannel* ToMessageChannel(NPObject* object) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<MessageChannel::MessageChannelNPObject*>(object)-> 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) message_channel.get(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPObject* ToPassThroughObject(NPObject* object) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageChannel* channel = ToMessageChannel(object); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel ? channel->passthrough_object() : NULL; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper function to determine if a given identifier is equal to kPostMessage. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IdentifierIsPostMessage(NPIdentifier identifier) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WebBindings::getStringIdentifier(kPostMessage) == identifier; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copy a PP_Var in to a PP_Var that is appropriate for sending via postMessage. 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// This currently just copies the value. For a string Var, the result is a 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// PP_Var with the a copy of |var|'s string contents and a reference count of 1. 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)PP_Var CopyPPVar(const PP_Var& var) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (var.type) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_VARTYPE_UNDEFINED: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_VARTYPE_NULL: 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_VARTYPE_BOOL: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_VARTYPE_INT32: 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_VARTYPE_DOUBLE: 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return var; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_VARTYPE_STRING: { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringVar* string = StringVar::FromPPVar(var); 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!string) 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return PP_MakeUndefined(); 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return StringVar::StringToPPVar(string->value()); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_VARTYPE_ARRAY_BUFFER: { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(var); 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!buffer) 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return PP_MakeUndefined(); 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PP_Var new_buffer_var = PpapiGlobals::Get()->GetVarTracker()-> 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) MakeArrayBufferPPVar(buffer->ByteLength()); 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(new_buffer_var.type == PP_VARTYPE_ARRAY_BUFFER); 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (new_buffer_var.type != PP_VARTYPE_ARRAY_BUFFER) 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return PP_MakeUndefined(); 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ArrayBufferVar* new_buffer = ArrayBufferVar::FromPPVar(new_buffer_var); 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(new_buffer); 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!new_buffer) 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return PP_MakeUndefined(); 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) memcpy(new_buffer->Map(), buffer->Map(), buffer->ByteLength()); 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return new_buffer_var; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_VARTYPE_OBJECT: 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_VARTYPE_ARRAY: 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PP_VARTYPE_DICTIONARY: 107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case PP_VARTYPE_RESOURCE: 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // These types are not supported by PostMessage in-process. In some rare 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // cases with the NaCl plugin, they may be sent but they will be dropped 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // anyway (see crbug.com/318837 for details). 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_MakeUndefined(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NOTREACHED(); 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return PP_MakeUndefined(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implementations of NPClass functions. These are here to: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Implement postMessage behavior. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Forward calls to the 'passthrough' object to allow backwards-compatibility 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with GetInstanceObject() objects. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPObject* MessageChannelAllocate(NPP npp, NPClass* the_class) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new MessageChannel::MessageChannelNPObject; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageChannelDeallocate(NPObject* object) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageChannel::MessageChannelNPObject* instance = 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<MessageChannel::MessageChannelNPObject*>(object); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete instance; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageChannelHasMethod(NPObject* np_obj, NPIdentifier name) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!np_obj) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only handle a function called postMessage. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IdentifierIsPostMessage(name)) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Other method names we will pass to the passthrough object, if we have one. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPObject* passthrough = ToPassThroughObject(np_obj); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (passthrough) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WebBindings::hasMethod(NULL, passthrough, name); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageChannelInvoke(NPObject* np_obj, NPIdentifier name, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NPVariant* args, uint32 arg_count, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPVariant* result) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!np_obj) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only handle a function called postMessage. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IdentifierIsPostMessage(name) && (arg_count == 1)) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageChannel* message_channel = ToMessageChannel(np_obj); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message_channel) { 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) message_channel->NPVariantToPPVar(&args[0]); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Other method calls we will pass to the passthrough object, if we have one. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPObject* passthrough = ToPassThroughObject(np_obj); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (passthrough) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WebBindings::invoke(NULL, passthrough, name, args, arg_count, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageChannelInvokeDefault(NPObject* np_obj, 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NPVariant* args, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 arg_count, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPVariant* result) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!np_obj) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invoke on the passthrough object, if we have one. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPObject* passthrough = ToPassThroughObject(np_obj); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (passthrough) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WebBindings::invokeDefault(NULL, passthrough, args, arg_count, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageChannelHasProperty(NPObject* np_obj, NPIdentifier name) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!np_obj) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MessageChannel* message_channel = ToMessageChannel(np_obj); 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (message_channel) { 195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (message_channel->GetReadOnlyProperty(name, NULL)) 196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invoke on the passthrough object, if we have one. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPObject* passthrough = ToPassThroughObject(np_obj); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (passthrough) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WebBindings::hasProperty(NULL, passthrough, name); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageChannelGetProperty(NPObject* np_obj, NPIdentifier name, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPVariant* result) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!np_obj) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't allow getting the postMessage function. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IdentifierIsPostMessage(name)) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MessageChannel* message_channel = ToMessageChannel(np_obj); 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (message_channel) { 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (message_channel->GetReadOnlyProperty(name, result)) 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invoke on the passthrough object, if we have one. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPObject* passthrough = ToPassThroughObject(np_obj); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (passthrough) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WebBindings::getProperty(NULL, passthrough, name, result); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageChannelSetProperty(NPObject* np_obj, NPIdentifier name, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NPVariant* variant) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!np_obj) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't allow setting the postMessage function. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IdentifierIsPostMessage(name)) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invoke on the passthrough object, if we have one. 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPObject* passthrough = ToPassThroughObject(np_obj); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (passthrough) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WebBindings::setProperty(NULL, passthrough, name, variant); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageChannelEnumerate(NPObject *np_obj, NPIdentifier **value, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t *count) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!np_obj) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invoke on the passthrough object, if we have one, to enumerate its 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // properties. 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPObject* passthrough = ToPassThroughObject(np_obj); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (passthrough) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = WebBindings::enumerate(NULL, passthrough, value, count); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (success) { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add postMessage to the list and return it. 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (std::numeric_limits<size_t>::max() / sizeof(NPIdentifier) <= 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<size_t>(*count) + 1) // Else, "always false" x64 warning. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPIdentifier* new_array = static_cast<NPIdentifier*>( 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::malloc(sizeof(NPIdentifier) * (*count + 1))); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::memcpy(new_array, *value, sizeof(NPIdentifier)*(*count)); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_array[*count] = WebBindings::getStringIdentifier(kPostMessage); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::free(*value); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = new_array; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++(*count); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, build an array that includes only postMessage. 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = static_cast<NPIdentifier*>(malloc(sizeof(NPIdentifier))); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*value)[0] = WebBindings::getStringIdentifier(kPostMessage); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *count = 1; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPClass message_channel_class = { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NP_CLASS_STRUCT_VERSION, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MessageChannelAllocate, 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MessageChannelDeallocate, 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MessageChannelHasMethod, 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MessageChannelInvoke, 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MessageChannelInvokeDefault, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MessageChannelHasProperty, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MessageChannelGetProperty, 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MessageChannelSetProperty, 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MessageChannelEnumerate, 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MessageChannel -------------------------------------------------------------- 2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct MessageChannel::VarConversionResult { 2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) VarConversionResult(const ppapi::ScopedPPVar& r, bool s) 2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : result(r), 2983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) success(s), 2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) conversion_completed(true) {} 3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) VarConversionResult() 3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : success(false), 3023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) conversion_completed(false) {} 3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi::ScopedPPVar result; 3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool success; 3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool conversion_completed; 3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageChannel::MessageChannelNPObject::MessageChannelNPObject() { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageChannel::MessageChannelNPObject::~MessageChannelNPObject() {} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben MurdochMessageChannel::MessageChannel(PepperPluginInstanceImpl* instance) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : instance_(instance), 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) passthrough_object_(NULL), 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np_object_(NULL), 3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) early_message_queue_state_(QUEUE_MESSAGES), 3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_ptr_factory_(this) { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now create an NPObject for receiving calls to postMessage. This sets the 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reference count to 1. We release it in the destructor. 32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NPObject* obj = WebBindings::createObject(instance_->instanceNPP(), 32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &message_channel_class); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(obj); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np_object_ = static_cast<MessageChannel::MessageChannelNPObject*>(obj); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np_object_->message_channel = weak_ptr_factory_.GetWeakPtr(); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MessageChannel::NPVariantToPPVar(const NPVariant* variant) { 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) converted_var_queue_.push_back(VarConversionResult()); 3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::list<VarConversionResult>::iterator result_iterator = 3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) --converted_var_queue_.end(); 3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (variant->type) { 3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case NPVariantType_Void: 3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NPVariantToPPVarComplete(result_iterator, 3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi::ScopedPPVar(PP_MakeUndefined()), true); 3363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case NPVariantType_Null: 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NPVariantToPPVarComplete(result_iterator, 3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi::ScopedPPVar(PP_MakeNull()), true); 3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case NPVariantType_Bool: 3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NPVariantToPPVarComplete(result_iterator, 3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi::ScopedPPVar( 3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PP_MakeBool(PP_FromBool(NPVARIANT_TO_BOOLEAN(*variant)))), 3453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) true); 3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case NPVariantType_Int32: 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NPVariantToPPVarComplete(result_iterator, 3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi::ScopedPPVar( 3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PP_MakeInt32(NPVARIANT_TO_INT32(*variant))), 3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) true); 3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case NPVariantType_Double: 3543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NPVariantToPPVarComplete(result_iterator, 3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi::ScopedPPVar( 3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant))), 3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) true); 3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case NPVariantType_String: 3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NPVariantToPPVarComplete(result_iterator, 3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi::ScopedPPVar(ppapi::ScopedPPVar::PassRef(), 3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringVar::StringToPPVar( 3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NPVARIANT_TO_STRING(*variant).UTF8Characters, 3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NPVARIANT_TO_STRING(*variant).UTF8Length)), 3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) true); 3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case NPVariantType_Object: { 3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Calling WebBindings::toV8Value creates a wrapper around NPVariant so it 3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // shouldn't result in a deep copy. 3703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) v8::Handle<v8::Value> v8_value = WebBindings::toV8Value(variant); 371424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) V8VarConverter(instance_->pp_instance()).FromV8Value( 372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8_value, v8::Isolate::GetCurrent()->GetCurrentContext(), 3733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&MessageChannel::NPVariantToPPVarComplete, 374424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), result_iterator)); 3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NPVariantToPPVarComplete(result_iterator, 3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi::ScopedPPVar(PP_MakeUndefined()), false); 3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageChannel::PostMessageToJavaScript(PP_Var message_data) { 38358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) v8::HandleScope scope(v8::Isolate::GetCurrent()); 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Because V8 is probably not on the stack for Native->JS calls, we need to 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // enter the appropriate context for the plugin. 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebPluginContainer* container = instance_->container(); 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // It's possible that container() is NULL if the plugin has been removed from 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the DOM (but the PluginInstance is not destroyed yet). 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!container) 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Local<v8::Context> context = 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) container->element().document().frame()->mainWorldScriptContext(); 395ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // If the page is being destroyed, the context may be empty. 396ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (context.IsEmpty()) 397ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Context::Scope context_scope(context); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) v8::Handle<v8::Value> v8_val; 401424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!V8VarConverter(instance_->pp_instance()).ToV8Value( 402424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) message_data, context, &v8_val)) { 4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PpapiGlobals::Get()->LogWithSource(instance_->pp_instance(), 4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_LOGLEVEL_ERROR, std::string(), kVarToV8ConversionError); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // This is for backward compatibility. It usually makes sense for us to return 40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // a string object rather than a string primitive because it allows multiple 41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // references to the same string (as with PP_Var strings). However, prior to 41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // implementing dictionary and array, vars we would return a string primitive 41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // here. Changing it to an object now will break existing code that uses 41390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // strict comparisons for strings returned from PostMessage. e.g. x === "123" 41490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // will no longer return true. So if the only value to return is a string 41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // object, just return the string primitive. 41690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (v8_val->IsStringObject()) 41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) v8_val = v8_val->ToString(); 41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebSerializedScriptValue serialized_val = 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebSerializedScriptValue::serialize(v8_val); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (instance_->module()->IsProxied()) { 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (early_message_queue_state_ != SEND_DIRECTLY) { 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We can't just PostTask here; the messages would arrive out of 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // order. Instead, we queue them up until we're ready to post 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // them. 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) early_message_queue_.push_back(serialized_val); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The proxy sent an asynchronous message, so the plugin is already 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // unblocked. Therefore, there's no need to PostTask. 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(early_message_queue_.size() == 0); 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostMessageToJavaScriptImpl(serialized_val); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 435b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&MessageChannel::PostMessageToJavaScriptImpl, 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) serialized_val)); 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessageChannel::StopQueueingJavaScriptMessages() { 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We PostTask here instead of draining the message queue directly 44558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch // since we haven't finished initializing the PepperWebPluginImpl yet, so 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the plugin isn't available in the DOM. 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) early_message_queue_state_ = DRAIN_PENDING; 448b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&MessageChannel::DrainEarlyMessageQueue, 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessageChannel::QueueJavaScriptMessages() { 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (early_message_queue_state_ == DRAIN_PENDING) 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) early_message_queue_state_ = DRAIN_CANCELLED; 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) early_message_queue_state_ = QUEUE_MESSAGES; 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MessageChannel::NPVariantToPPVarComplete( 4623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::list<VarConversionResult>::iterator& result_iterator, 4633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const ppapi::ScopedPPVar& result, 4643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool success) { 4653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *result_iterator = VarConversionResult(result, success); 4663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::list<VarConversionResult>::iterator it = converted_var_queue_.begin(); 4673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) while (it != converted_var_queue_.end() && it->conversion_completed) { 4683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (it->success) { 4693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PostMessageToNative(it->result.get()); 4703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 4713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PpapiGlobals::Get()->LogWithSource(instance()->pp_instance(), 4723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PP_LOGLEVEL_ERROR, std::string(), kV8ToVarConversionError); 4733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) converted_var_queue_.erase(it++); 4763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessageChannel::DrainEarlyMessageQueue() { 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Take a reference on the PluginInstance. This is because JavaScript code 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // may delete the plugin, which would destroy the PluginInstance and its 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // corresponding MessageChannel. 48358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch scoped_refptr<PepperPluginInstanceImpl> instance_ref(instance_); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (early_message_queue_state_ == DRAIN_CANCELLED) { 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) early_message_queue_state_ = QUEUE_MESSAGES; 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(early_message_queue_state_ == DRAIN_PENDING); 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (!early_message_queue_.empty()) { 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostMessageToJavaScriptImpl(early_message_queue_.front()); 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) early_message_queue_.pop_front(); 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) early_message_queue_state_ = SEND_DIRECTLY; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageChannel::PostMessageToJavaScriptImpl( 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WebSerializedScriptValue& message_data) { 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(instance_); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebPluginContainer* container = instance_->container(); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's possible that container() is NULL if the plugin has been removed from 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the DOM (but the PluginInstance is not destroyed yet). 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!container) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebDOMEvent event = 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) container->element().document().createEvent("MessageEvent"); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebDOMMessageEvent msg_event = event.to<WebDOMMessageEvent>(); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg_event.initMessageEvent("message", // type 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, // canBubble 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, // cancelable 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data, // data 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "", // origin [*] 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // source [*] 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ""); // lastEventId 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // [*] Note that the |origin| is only specified for cross-document and server- 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sent messages, while |source| is only specified for cross-document 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // messages: 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This currently behaves like Web Workers. On Firefox, Chrome, and Safari 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // at least, postMessage on Workers does not provide the origin or source. 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(dmichael): Add origin if we change to a more iframe-like origin 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // policy (see crbug.com/81537) 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) container->element().dispatchEvent(msg_event); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageChannel::PostMessageToNative(PP_Var message_data) { 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (instance_->module()->IsProxied()) { 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In the proxied case, the copy will happen via serializiation, and the 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // message is asynchronous. Therefore there's no need to copy the Var, nor 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to PostTask. 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostMessageToNativeImpl(message_data); 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make a copy of the message data for the Task we will run. 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PP_Var var_copy(CopyPPVar(message_data)); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 540b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 541b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) FROM_HERE, 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&MessageChannel::PostMessageToNativeImpl, 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var_copy)); 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageChannel::PostMessageToNativeImpl(PP_Var message_data) { 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->HandleMessage(message_data); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageChannel::~MessageChannel() { 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebBindings::releaseObject(np_object_); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (passthrough_object_) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebBindings::releaseObject(passthrough_object_); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageChannel::SetPassthroughObject(NPObject* passthrough) { 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Retain the passthrough object; We need to ensure it lives as long as this 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MessageChannel. 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (passthrough) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebBindings::retainObject(passthrough); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we had a passthrough set already, release it. Note that we retain the 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // incoming passthrough object first, so that we behave correctly if anyone 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // invokes: 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SetPassthroughObject(passthrough_object()); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (passthrough_object_) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebBindings::releaseObject(passthrough_object_); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) passthrough_object_ = passthrough; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool MessageChannel::GetReadOnlyProperty(NPIdentifier key, 575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NPVariant *value) const { 576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::map<NPIdentifier, ppapi::ScopedPPVar>::const_iterator it = 577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) internal_properties_.find(key); 578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (it != internal_properties_.end()) { 579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (value) 580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return PPVarToNPVariant(it->second.get(), value); 581f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 584f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MessageChannel::SetReadOnlyProperty(PP_Var key, PP_Var value) { 587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) internal_properties_[PPVarToNPIdentifier(key)] = ppapi::ScopedPPVar(value); 588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 59058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch} // namespace content 591