Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CONTENT_RENDERER_PEPPER_MESSAGE_CHANNEL_H_ | 5 #ifndef CONTENT_RENDERER_PEPPER_MESSAGE_CHANNEL_H_ |
| 6 #define CONTENT_RENDERER_PEPPER_MESSAGE_CHANNEL_H_ | 6 #define CONTENT_RENDERER_PEPPER_MESSAGE_CHANNEL_H_ |
| 7 | 7 |
| 8 #include <deque> | 8 #include <deque> |
| 9 #include <list> | 9 #include <list> |
| 10 #include <map> | 10 #include <map> |
| 11 | 11 |
| 12 #include "base/basictypes.h" | |
| 12 #include "base/memory/weak_ptr.h" | 13 #include "base/memory/weak_ptr.h" |
| 14 #include "gin/handle.h" | |
| 15 #include "gin/interceptor.h" | |
| 16 #include "gin/wrappable.h" | |
| 13 #include "ppapi/shared_impl/resource.h" | 17 #include "ppapi/shared_impl/resource.h" |
| 14 #include "third_party/WebKit/public/web/WebSerializedScriptValue.h" | 18 #include "third_party/WebKit/public/web/WebSerializedScriptValue.h" |
| 15 #include "third_party/npapi/bindings/npruntime.h" | 19 #include "v8/include/v8.h" |
| 16 | 20 |
| 17 struct PP_Var; | 21 struct PP_Var; |
| 18 | 22 |
| 23 namespace gin { | |
| 24 class Arguments; | |
| 25 } // namespace gin | |
| 26 | |
| 19 namespace ppapi { | 27 namespace ppapi { |
| 20 class ScopedPPVar; | 28 class ScopedPPVar; |
| 21 } | 29 } // namespace ppapi |
| 22 | 30 |
| 23 namespace content { | 31 namespace content { |
| 24 | 32 |
| 25 class PepperPluginInstanceImpl; | 33 class PepperPluginInstanceImpl; |
| 34 class PluginObject; | |
| 26 | 35 |
| 27 // MessageChannel implements bidirectional postMessage functionality, allowing | 36 // MessageChannel implements bidirectional postMessage functionality, allowing |
| 28 // calls from JavaScript to plugins and vice-versa. See | 37 // calls from JavaScript to plugins and vice-versa. See |
| 29 // PPB_Messaging::PostMessage and PPP_Messaging::HandleMessage for more | 38 // PPB_Messaging::PostMessage and PPP_Messaging::HandleMessage for more |
| 30 // information. | 39 // information. |
| 31 // | 40 // |
| 32 // Currently, only 1 MessageChannel can exist, to implement postMessage | 41 // Currently, only 1 MessageChannel can exist, to implement postMessage |
| 33 // functionality for the instance interfaces. In the future, when we create a | 42 // functionality for the instance interfaces. In the future, when we create a |
| 34 // MessagePort type in PPAPI, those may be implemented here as well with some | 43 // MessagePort type in PPAPI, those may be implemented here as well with some |
| 35 // refactoring. | 44 // refactoring. |
| 36 // - Separate message ports won't require the passthrough object. | 45 // - Separate message ports won't require the passthrough object. |
| 37 // - The message target won't be limited to instance, and should support | 46 // - The message target won't be limited to instance, and should support |
| 38 // either plugin-provided or JS objects. | 47 // either plugin-provided or JS objects. |
| 39 // TODO(dmichael): Add support for separate MessagePorts. | 48 // TODO(dmichael): Add support for separate MessagePorts. |
| 40 class MessageChannel { | 49 class MessageChannel : public gin::Wrappable<MessageChannel>, |
| 50 public gin::NamedPropertyInterceptor, | |
| 51 public gin::IndexedPropertyInterceptor { | |
| 41 public: | 52 public: |
| 42 // MessageChannelNPObject is a simple struct that adds a pointer back to a | 53 static gin::WrapperInfo kWrapperInfo; |
|
dmichael (off chromium)
2014/08/20 23:09:15
Can it be made const?
| |
| 43 // MessageChannel instance. This way, we can use an NPObject to allow | |
| 44 // JavaScript interactions without forcing MessageChannel to inherit from | |
| 45 // NPObject. | |
| 46 struct MessageChannelNPObject : public NPObject { | |
| 47 MessageChannelNPObject(); | |
| 48 ~MessageChannelNPObject(); | |
| 49 | 54 |
| 50 base::WeakPtr<MessageChannel> message_channel; | 55 static void Create(PepperPluginInstanceImpl* instance, |
| 51 }; | 56 v8::Persistent<v8::Object>* result); |
| 52 | 57 |
| 53 explicit MessageChannel(PepperPluginInstanceImpl* instance); | 58 virtual ~MessageChannel(); |
| 54 ~MessageChannel(); | 59 |
| 60 // gin::NamedPropertyInterceptor | |
| 61 virtual v8::Local<v8::Value> GetNamedProperty( | |
| 62 v8::Isolate* isolate, | |
| 63 const std::string& property) OVERRIDE; | |
| 64 virtual void SetNamedProperty(v8::Isolate* isolate, | |
| 65 const std::string& property, | |
| 66 v8::Local<v8::Value> value) OVERRIDE; | |
| 67 virtual std::vector<std::string> EnumerateNamedProperties( | |
| 68 v8::Isolate* isolate) OVERRIDE; | |
| 69 | |
| 70 // gin::IndexedPropertyInterceptor | |
| 71 virtual v8::Local<v8::Value> GetIndexedProperty(v8::Isolate* isolate, | |
| 72 uint32_t index) OVERRIDE; | |
| 73 virtual void SetIndexedProperty(v8::Isolate* isolate, | |
| 74 uint32_t index, | |
| 75 v8::Local<v8::Value> value) OVERRIDE; | |
| 76 virtual std::vector<uint32_t> EnumerateIndexedProperties( | |
| 77 v8::Isolate* isolate) OVERRIDE; | |
| 78 | |
| 79 // Post a message to the onmessage handler for this channel's instance | |
| 80 // asynchronously. | |
| 81 void PostMessageToJavaScript(PP_Var message_data); | |
| 55 | 82 |
| 56 // Messages are queued initially. After the PepperPluginInstanceImpl is ready | 83 // Messages are queued initially. After the PepperPluginInstanceImpl is ready |
| 57 // to send and handle messages, users of MessageChannel should call | 84 // to send and handle messages, users of MessageChannel should call |
| 58 // Start(). | 85 // Start(). |
| 59 void Start(); | 86 void Start(); |
| 60 | 87 |
| 61 // Return the NPObject* to which we should forward any calls which aren't | 88 // Set the V8Object to which we should forward any calls which aren't |
| 62 // related to postMessage. Note that this can be NULL; it only gets set if | 89 // related to postMessage. Note that this can be empty; it only gets set if |
| 63 // there is a scriptable 'InstanceObject' associated with this channel's | 90 // there is a scriptable 'InstanceObject' associated with this channel's |
| 64 // instance. | 91 // instance. |
| 65 NPObject* passthrough_object() { return passthrough_object_; } | 92 void SetPassthroughObject(v8::Handle<v8::Object> passthrough); |
| 66 void SetPassthroughObject(NPObject* passthrough); | |
| 67 | |
| 68 NPObject* np_object() { return np_object_; } | |
| 69 | 93 |
| 70 PepperPluginInstanceImpl* instance() { return instance_; } | 94 PepperPluginInstanceImpl* instance() { return instance_; } |
| 71 | 95 |
| 72 bool GetReadOnlyProperty(NPIdentifier key, NPVariant* value) const; | |
| 73 void SetReadOnlyProperty(PP_Var key, PP_Var value); | 96 void SetReadOnlyProperty(PP_Var key, PP_Var value); |
| 74 | 97 |
| 75 // Post a message to the onmessage handler for this channel's instance | 98 private: |
| 76 // asynchronously. | 99 // Struct for storing the result of a v8 object being converted to a PP_Var. |
| 77 void PostMessageToJavaScript(PP_Var message_data); | 100 struct VarConversionResult; |
| 101 | |
| 102 explicit MessageChannel(PepperPluginInstanceImpl* instance); | |
| 103 | |
| 104 // gin::Wrappable | |
| 105 virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder( | |
| 106 v8::Isolate* isolate) OVERRIDE; | |
| 78 | 107 |
| 79 // Post a message to the plugin's HandleMessage function for this channel's | 108 // Post a message to the plugin's HandleMessage function for this channel's |
| 80 // instance. | 109 // instance. |
| 81 void PostMessageToNative(const NPVariant* message_data); | 110 void PostMessageToNative(gin::Arguments* args); |
| 82 | |
| 83 // Post a message to the plugin's HandleBlocking Message function for this | 111 // Post a message to the plugin's HandleBlocking Message function for this |
| 84 // channel's instance synchronously, and return a result. | 112 // channel's instance synchronously, and return a result. |
| 85 void PostBlockingMessageToNative(const NPVariant* message_data, | 113 void PostBlockingMessageToNative(gin::Arguments* args); |
| 86 NPVariant* np_result); | |
| 87 | |
| 88 private: | |
| 89 // Struct for storing the result of a NPVariant being converted to a PP_Var. | |
| 90 struct VarConversionResult; | |
| 91 | 114 |
| 92 // Post a message to the onmessage handler for this channel's instance | 115 // Post a message to the onmessage handler for this channel's instance |
| 93 // synchronously. This is used by PostMessageToJavaScript. | 116 // synchronously. This is used by PostMessageToJavaScript. |
| 94 void PostMessageToJavaScriptImpl( | 117 void PostMessageToJavaScriptImpl( |
| 95 const blink::WebSerializedScriptValue& message_data); | 118 const blink::WebSerializedScriptValue& message_data); |
| 96 | 119 |
| 97 void EnqueuePluginMessage(const NPVariant* variant); | 120 PluginObject* GetPluginObject(v8::Isolate* isolate); |
| 121 | |
| 122 void EnqueuePluginMessage(v8::Handle<v8::Value> v8_value); | |
| 98 | 123 |
| 99 void FromV8ValueComplete(VarConversionResult* result_holder, | 124 void FromV8ValueComplete(VarConversionResult* result_holder, |
| 100 const ppapi::ScopedPPVar& result_var, | 125 const ppapi::ScopedPPVar& result_var, |
| 101 bool success); | 126 bool success); |
| 102 | 127 |
| 103 void DrainCompletedPluginMessages(); | 128 void DrainCompletedPluginMessages(); |
| 104 void DrainEarlyMessageQueue(); | 129 void DrainEarlyMessageQueue(); |
| 105 | 130 |
| 106 PepperPluginInstanceImpl* instance_; | 131 PepperPluginInstanceImpl* instance_; |
| 107 | 132 |
| 108 // We pass all non-postMessage calls through to the passthrough_object_. | 133 // We pass all non-postMessage calls through to the passthrough_object_. |
| 109 // This way, a plugin can use PPB_Class or PPP_Class_Deprecated and also | 134 // This way, a plugin can use PPB_Class or PPP_Class_Deprecated and also |
| 110 // postMessage. This is necessary to support backwards-compatibility, and | 135 // postMessage. This is necessary to support backwards-compatibility, and |
| 111 // also trusted plugins for which we will continue to support synchronous | 136 // also trusted plugins for which we will continue to support synchronous |
| 112 // scripting. | 137 // scripting. |
| 113 NPObject* passthrough_object_; | 138 v8::Persistent<v8::Object> passthrough_object_; |
| 114 | |
| 115 // The NPObject we use to expose postMessage to JavaScript. | |
| 116 MessageChannelNPObject* np_object_; | |
| 117 | 139 |
| 118 std::deque<blink::WebSerializedScriptValue> early_message_queue_; | 140 std::deque<blink::WebSerializedScriptValue> early_message_queue_; |
| 119 enum EarlyMessageQueueState { | 141 enum EarlyMessageQueueState { |
| 120 QUEUE_MESSAGES, // Queue JS messages. | 142 QUEUE_MESSAGES, // Queue JS messages. |
| 121 SEND_DIRECTLY, // Post JS messages directly. | 143 SEND_DIRECTLY, // Post JS messages directly. |
| 122 }; | 144 }; |
| 123 EarlyMessageQueueState early_message_queue_state_; | 145 EarlyMessageQueueState early_message_queue_state_; |
| 124 | 146 |
| 125 // This queue stores vars that are being sent to the plugin. Because | 147 // This queue stores vars that are being sent to the plugin. Because |
| 126 // conversion can happen asynchronously for object types, the queue stores | 148 // conversion can happen asynchronously for object types, the queue stores |
| 127 // the var until all previous vars have been converted and sent. This | 149 // the var until all previous vars have been converted and sent. This |
| 128 // preserves the order in which JS->plugin messages are processed. | 150 // preserves the order in which JS->plugin messages are processed. |
| 129 // | 151 // |
| 130 // Note we rely on raw VarConversionResult* pointers remaining valid after | 152 // Note we rely on raw VarConversionResult* pointers remaining valid after |
| 131 // calls to push_back or pop_front; hence why we're using list. (deque would | 153 // calls to push_back or pop_front; hence why we're using list. (deque would |
| 132 // probably also work, but is less clearly specified). | 154 // probably also work, but is less clearly specified). |
| 133 std::list<VarConversionResult> plugin_message_queue_; | 155 std::list<VarConversionResult> plugin_message_queue_; |
| 134 | 156 |
| 135 std::map<NPIdentifier, ppapi::ScopedPPVar> internal_properties_; | 157 std::map<std::string, ppapi::ScopedPPVar> internal_named_properties_; |
| 158 std::map<uint32_t, ppapi::ScopedPPVar> internal_indexed_properties_; | |
| 136 | 159 |
| 137 // This is used to ensure pending tasks will not fire after this object is | 160 // This is used to ensure pending tasks will not fire after this object is |
| 138 // destroyed. | 161 // destroyed. |
| 139 base::WeakPtrFactory<MessageChannel> weak_ptr_factory_; | 162 base::WeakPtrFactory<MessageChannel> weak_ptr_factory_; |
| 140 | 163 |
| 141 DISALLOW_COPY_AND_ASSIGN(MessageChannel); | 164 DISALLOW_COPY_AND_ASSIGN(MessageChannel); |
| 142 }; | 165 }; |
| 143 | 166 |
| 144 } // namespace content | 167 } // namespace content |
| 145 | 168 |
| 146 #endif // CONTENT_RENDERER_PEPPER_MESSAGE_CHANNEL_H_ | 169 #endif // CONTENT_RENDERER_PEPPER_MESSAGE_CHANNEL_H_ |
| 170 | |
| OLD | NEW |