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 { |
41 public: | 51 public: |
42 // MessageChannelNPObject is a simple struct that adds a pointer back to a | 52 static gin::WrapperInfo kWrapperInfo; |
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 | 53 |
50 base::WeakPtr<MessageChannel> message_channel; | 54 // Creates a MessageChannel, returning a pointer to it and sets |result| to |
51 }; | 55 // the v8 object which is backed by the message channel. The returned pointer |
| 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); |
52 | 59 |
53 explicit MessageChannel(PepperPluginInstanceImpl* instance); | 60 virtual ~MessageChannel(); |
54 ~MessageChannel(); | 61 |
| 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); |
55 | 69 |
56 // Messages are queued initially. After the PepperPluginInstanceImpl is ready | 70 // Messages are queued initially. After the PepperPluginInstanceImpl is ready |
57 // to send and handle messages, users of MessageChannel should call | 71 // to send and handle messages, users of MessageChannel should call |
58 // Start(). | 72 // Start(). |
59 void Start(); | 73 void Start(); |
60 | 74 |
61 // Return the NPObject* to which we should forward any calls which aren't | 75 // 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 | 76 // 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 | 77 // there is a scriptable 'InstanceObject' associated with this channel's |
64 // instance. | 78 // instance. |
65 NPObject* passthrough_object() { return passthrough_object_; } | 79 void SetPassthroughObject(v8::Handle<v8::Object> passthrough); |
66 void SetPassthroughObject(NPObject* passthrough); | |
67 | |
68 NPObject* np_object() { return np_object_; } | |
69 | 80 |
70 PepperPluginInstanceImpl* instance() { return instance_; } | 81 PepperPluginInstanceImpl* instance() { return instance_; } |
71 | 82 |
72 bool GetReadOnlyProperty(NPIdentifier key, NPVariant* value) const; | |
73 void SetReadOnlyProperty(PP_Var key, PP_Var value); | 83 void SetReadOnlyProperty(PP_Var key, PP_Var value); |
74 | 84 |
75 // Post a message to the onmessage handler for this channel's instance | 85 private: |
76 // asynchronously. | 86 // Struct for storing the result of a v8 object being converted to a PP_Var. |
77 void PostMessageToJavaScript(PP_Var message_data); | 87 struct VarConversionResult; |
| 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; |
78 | 104 |
79 // Post a message to the plugin's HandleMessage function for this channel's | 105 // Post a message to the plugin's HandleMessage function for this channel's |
80 // instance. | 106 // instance. |
81 void PostMessageToNative(const NPVariant* message_data); | 107 void PostMessageToNative(gin::Arguments* args); |
82 | |
83 // Post a message to the plugin's HandleBlocking Message function for this | 108 // Post a message to the plugin's HandleBlocking Message function for this |
84 // channel's instance synchronously, and return a result. | 109 // channel's instance synchronously, and return a result. |
85 void PostBlockingMessageToNative(const NPVariant* message_data, | 110 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 | 111 |
92 // Post a message to the onmessage handler for this channel's instance | 112 // Post a message to the onmessage handler for this channel's instance |
93 // synchronously. This is used by PostMessageToJavaScript. | 113 // synchronously. This is used by PostMessageToJavaScript. |
94 void PostMessageToJavaScriptImpl( | 114 void PostMessageToJavaScriptImpl( |
95 const blink::WebSerializedScriptValue& message_data); | 115 const blink::WebSerializedScriptValue& message_data); |
96 | 116 |
97 void EnqueuePluginMessage(const NPVariant* variant); | 117 PluginObject* GetPluginObject(v8::Isolate* isolate); |
| 118 |
| 119 void EnqueuePluginMessage(v8::Handle<v8::Value> v8_value); |
98 | 120 |
99 void FromV8ValueComplete(VarConversionResult* result_holder, | 121 void FromV8ValueComplete(VarConversionResult* result_holder, |
100 const ppapi::ScopedPPVar& result_var, | 122 const ppapi::ScopedPPVar& result_var, |
101 bool success); | 123 bool success); |
102 | 124 |
103 void DrainCompletedPluginMessages(); | 125 void DrainCompletedPluginMessages(); |
104 void DrainEarlyMessageQueue(); | 126 void DrainEarlyMessageQueue(); |
105 | 127 |
106 PepperPluginInstanceImpl* instance_; | 128 PepperPluginInstanceImpl* instance_; |
107 | 129 |
108 // We pass all non-postMessage calls through to the passthrough_object_. | 130 // 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 | 131 // This way, a plugin can use PPB_Class or PPP_Class_Deprecated and also |
110 // postMessage. This is necessary to support backwards-compatibility, and | 132 // postMessage. This is necessary to support backwards-compatibility, and |
111 // also trusted plugins for which we will continue to support synchronous | 133 // also trusted plugins for which we will continue to support synchronous |
112 // scripting. | 134 // scripting. |
113 NPObject* passthrough_object_; | 135 v8::Persistent<v8::Object> passthrough_object_; |
114 | |
115 // The NPObject we use to expose postMessage to JavaScript. | |
116 MessageChannelNPObject* np_object_; | |
117 | 136 |
118 std::deque<blink::WebSerializedScriptValue> early_message_queue_; | 137 std::deque<blink::WebSerializedScriptValue> early_message_queue_; |
119 enum EarlyMessageQueueState { | 138 enum EarlyMessageQueueState { |
120 QUEUE_MESSAGES, // Queue JS messages. | 139 QUEUE_MESSAGES, // Queue JS messages. |
121 SEND_DIRECTLY, // Post JS messages directly. | 140 SEND_DIRECTLY, // Post JS messages directly. |
122 }; | 141 }; |
123 EarlyMessageQueueState early_message_queue_state_; | 142 EarlyMessageQueueState early_message_queue_state_; |
124 | 143 |
125 // This queue stores vars that are being sent to the plugin. Because | 144 // This queue stores vars that are being sent to the plugin. Because |
126 // conversion can happen asynchronously for object types, the queue stores | 145 // conversion can happen asynchronously for object types, the queue stores |
127 // the var until all previous vars have been converted and sent. This | 146 // the var until all previous vars have been converted and sent. This |
128 // preserves the order in which JS->plugin messages are processed. | 147 // preserves the order in which JS->plugin messages are processed. |
129 // | 148 // |
130 // Note we rely on raw VarConversionResult* pointers remaining valid after | 149 // 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 | 150 // calls to push_back or pop_front; hence why we're using list. (deque would |
132 // probably also work, but is less clearly specified). | 151 // probably also work, but is less clearly specified). |
133 std::list<VarConversionResult> plugin_message_queue_; | 152 std::list<VarConversionResult> plugin_message_queue_; |
134 | 153 |
135 std::map<NPIdentifier, ppapi::ScopedPPVar> internal_properties_; | 154 std::map<std::string, ppapi::ScopedPPVar> internal_named_properties_; |
136 | 155 |
137 // This is used to ensure pending tasks will not fire after this object is | 156 // This is used to ensure pending tasks will not fire after this object is |
138 // destroyed. | 157 // destroyed. |
139 base::WeakPtrFactory<MessageChannel> weak_ptr_factory_; | 158 base::WeakPtrFactory<MessageChannel> weak_ptr_factory_; |
140 | 159 |
141 DISALLOW_COPY_AND_ASSIGN(MessageChannel); | 160 DISALLOW_COPY_AND_ASSIGN(MessageChannel); |
142 }; | 161 }; |
143 | 162 |
144 } // namespace content | 163 } // namespace content |
145 | 164 |
146 #endif // CONTENT_RENDERER_PEPPER_MESSAGE_CHANNEL_H_ | 165 #endif // CONTENT_RENDERER_PEPPER_MESSAGE_CHANNEL_H_ |
OLD | NEW |