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#ifndef CONTENT_RENDERER_PEPPER_MESSAGE_CHANNEL_H_ 6bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#define CONTENT_RENDERER_PEPPER_MESSAGE_CHANNEL_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <deque> 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <list> 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <map> 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/resource.h" 147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebSerializedScriptValue.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/npapi/bindings/npruntime.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PP_Var; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace ppapi { 203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class ScopedPPVar; 213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochnamespace content { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochclass PepperPluginInstanceImpl; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MessageChannel implements bidirectional postMessage functionality, allowing 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// calls from JavaScript to plugins and vice-versa. See 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PPB_Messaging::PostMessage and PPP_Messaging::HandleMessage for more 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// information. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Currently, only 1 MessageChannel can exist, to implement postMessage 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// functionality for the instance interfaces. In the future, when we create a 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MessagePort type in PPAPI, those may be implemented here as well with some 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// refactoring. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Separate message ports won't require the passthrough object. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - The message target won't be limited to instance, and should support 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// either plugin-provided or JS objects. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(dmichael): Add support for separate MessagePorts. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MessageChannel { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MessageChannelNPObject is a simple struct that adds a pointer back to a 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MessageChannel instance. This way, we can use an NPObject to allow 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // JavaScript interactions without forcing MessageChannel to inherit from 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NPObject. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct MessageChannelNPObject : public NPObject { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageChannelNPObject(); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~MessageChannelNPObject(); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<MessageChannel> message_channel; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch explicit MessageChannel(PepperPluginInstanceImpl* instance); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~MessageChannel(); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Converts an NPVariant to a PP_Var. This occurs asynchronously and 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // NPVariantToPPVarComplete will be called upon completion. 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void NPVariantToPPVar(const NPVariant* variant); 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post a message to the onmessage handler for this channel's instance 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // asynchronously. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PostMessageToJavaScript(PP_Var message_data); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post a message to the PPP_Instance HandleMessage function for this 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // channel's instance. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PostMessageToNative(PP_Var message_data); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return the NPObject* to which we should forward any calls which aren't 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // related to postMessage. Note that this can be NULL; it only gets set if 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there is a scriptable 'InstanceObject' associated with this channel's 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instance. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPObject* passthrough_object() { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return passthrough_object_; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetPassthroughObject(NPObject* passthrough); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPObject* np_object() { return np_object_; } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch PepperPluginInstanceImpl* instance() { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return instance_; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Messages sent to JavaScript are queued by default. After the DOM is 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // set up for the plugin, users of MessageChannel should call 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // StopQueueingJavaScriptMessages to start dispatching messages to JavaScript. 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void QueueJavaScriptMessages(); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void StopQueueingJavaScriptMessages(); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool GetReadOnlyProperty(NPIdentifier key, NPVariant* value) const; 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void SetReadOnlyProperty(PP_Var key, PP_Var value); 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Struct for storing the result of a NPVariant being converted to a PP_Var. 933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) struct VarConversionResult; 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // This is called when an NPVariant is finished being converted. 963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // |result_iteartor| is an iterator into |converted_var_queue_| where the 973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // result should be stored. 983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void NPVariantToPPVarComplete( 993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::list<VarConversionResult>::iterator& result_iterator, 1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const ppapi::ScopedPPVar& result, 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool success); 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch PepperPluginInstanceImpl* instance_; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We pass all non-postMessage calls through to the passthrough_object_. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This way, a plugin can use PPB_Class or PPP_Class_Deprecated and also 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // postMessage. This is necessary to support backwards-compatibility, and 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // also trusted plugins for which we will continue to support synchronous 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // scripting. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPObject* passthrough_object_; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The NPObject we use to expose postMessage to JavaScript. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageChannelNPObject* np_object_; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post a message to the onmessage handler for this channel's instance 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // synchronously. This is used by PostMessageToJavaScript. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PostMessageToJavaScriptImpl( 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebSerializedScriptValue& message_data); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post a message to the PPP_Instance HandleMessage function for this 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // channel's instance. This is used by PostMessageToNative. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PostMessageToNativeImpl(PP_Var message_data); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void DrainEarlyMessageQueue(); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(teravest): Remove all the tricky DRAIN_CANCELLED logic once 12658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch // PluginInstance::ResetAsProxied() is gone. 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::deque<blink::WebSerializedScriptValue> early_message_queue_; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum EarlyMessageQueueState { 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QUEUE_MESSAGES, // Queue JS messages. 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SEND_DIRECTLY, // Post JS messages directly. 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DRAIN_PENDING, // Drain queue, then transition to DIRECT. 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DRAIN_CANCELLED // Preempt drain, go back to QUEUE. 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EarlyMessageQueueState early_message_queue_state_; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // This queue stores vars that have been converted from NPVariants. Because 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // conversion can happen asynchronously, the queue stores the var until all 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // previous vars have been converted before calling PostMessage to ensure that 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the order in which messages are processed is preserved. 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::list<VarConversionResult> converted_var_queue_; 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::map<NPIdentifier, ppapi::ScopedPPVar> internal_properties_; 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // This is used to ensure pending tasks will not fire after this object is 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // destroyed. 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::WeakPtrFactory<MessageChannel> weak_ptr_factory_; 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MessageChannel); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch} // namespace content 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 153bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#endif // CONTENT_RENDERER_PEPPER_MESSAGE_CHANNEL_H_ 154