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