OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #include "ppapi/proxy/message_handler.h" | 5 #include "ppapi/proxy/message_handler.h" |
6 | 6 |
7 #include "ipc/ipc_message.h" | 7 #include "ipc/ipc_message.h" |
8 #include "ppapi/proxy/plugin_dispatcher.h" | 8 #include "ppapi/proxy/plugin_dispatcher.h" |
9 #include "ppapi/proxy/ppapi_messages.h" | 9 #include "ppapi/proxy/ppapi_messages.h" |
10 #include "ppapi/proxy/ppb_message_loop_proxy.h" | 10 #include "ppapi/proxy/ppb_message_loop_proxy.h" |
11 #include "ppapi/shared_impl/proxy_lock.h" | 11 #include "ppapi/shared_impl/proxy_lock.h" |
12 #include "ppapi/shared_impl/scoped_pp_var.h" | 12 #include "ppapi/shared_impl/scoped_pp_var.h" |
13 #include "ppapi/thunk/enter.h" | 13 #include "ppapi/thunk/enter.h" |
14 | 14 |
15 namespace ppapi { | 15 namespace ppapi { |
16 namespace proxy { | 16 namespace proxy { |
17 namespace { | 17 namespace { |
18 | 18 |
19 typedef void (*HandleMessageFunc)(PP_Instance, void*, const PP_Var*); | 19 typedef void (*HandleMessageFunc)(PP_Instance, void*, const PP_Var*); |
20 typedef void (*HandleBlockingMessageFunc)( | 20 typedef void (*HandleBlockingMessageFunc)( |
21 PP_Instance, void*, const PP_Var*, PP_Var*); | 21 PP_Instance, void*, const PP_Var*, PP_Var*); |
22 typedef void (*HandleMessageFunc_0_1)(PP_Instance, void*, PP_Var); | |
23 typedef PP_Var (*HandleBlockingMessageFunc_0_1)(PP_Instance, void*, PP_Var); | |
24 | 22 |
25 void HandleMessageWrapper(HandleMessageFunc function, | 23 void HandleMessageWrapper(HandleMessageFunc function, |
26 PP_Instance instance, | 24 PP_Instance instance, |
27 void* user_data, | 25 void* user_data, |
28 ScopedPPVar message_data) { | 26 ScopedPPVar message_data) { |
29 CallWhileUnlocked(function, instance, user_data, | 27 CallWhileUnlocked(function, instance, user_data, |
30 &message_data.get()); | 28 &message_data.get()); |
31 } | 29 } |
32 | 30 |
33 void HandleBlockingMessageWrapper(HandleBlockingMessageFunc function, | 31 void HandleBlockingMessageWrapper(HandleBlockingMessageFunc function, |
(...skipping 11 matching lines...) Expand all Loading... |
45 function, instance, user_data, &message_data.get(), &result); | 43 function, instance, user_data, &message_data.get(), &result); |
46 MessageLoopResource::GetCurrent()-> | 44 MessageLoopResource::GetCurrent()-> |
47 set_currently_handling_blocking_message(false); | 45 set_currently_handling_blocking_message(false); |
48 PpapiMsg_PPPMessageHandler_HandleBlockingMessage::WriteReplyParams( | 46 PpapiMsg_PPPMessageHandler_HandleBlockingMessage::WriteReplyParams( |
49 reply_msg.get(), | 47 reply_msg.get(), |
50 SerializedVarReturnValue::Convert(dispatcher, result), | 48 SerializedVarReturnValue::Convert(dispatcher, result), |
51 true /* was_handled */); | 49 true /* was_handled */); |
52 dispatcher->Send(reply_msg.release()); | 50 dispatcher->Send(reply_msg.release()); |
53 } | 51 } |
54 | 52 |
55 // TODO(dmichael): Remove the 0_1 verions; crbug.com/414398 | |
56 void HandleMessageWrapper_0_1(HandleMessageFunc_0_1 function, | |
57 PP_Instance instance, | |
58 void* user_data, | |
59 ScopedPPVar message_data) { | |
60 CallWhileUnlocked(function, instance, user_data, message_data.get()); | |
61 } | |
62 | |
63 void HandleBlockingMessageWrapper_0_1(HandleBlockingMessageFunc_0_1 function, | |
64 PP_Instance instance, | |
65 void* user_data, | |
66 ScopedPPVar message_data, | |
67 scoped_ptr<IPC::Message> reply_msg) { | |
68 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); | |
69 if (!dispatcher) | |
70 return; | |
71 MessageLoopResource::GetCurrent()-> | |
72 set_currently_handling_blocking_message(true); | |
73 PP_Var return_value = CallWhileUnlocked(function, | |
74 instance, | |
75 user_data, | |
76 message_data.get()); | |
77 MessageLoopResource::GetCurrent()-> | |
78 set_currently_handling_blocking_message(false); | |
79 PpapiMsg_PPPMessageHandler_HandleBlockingMessage::WriteReplyParams( | |
80 reply_msg.get(), | |
81 SerializedVarReturnValue::Convert(dispatcher, return_value), | |
82 true /* was_handled */); | |
83 dispatcher->Send(reply_msg.release()); | |
84 } | |
85 | |
86 } // namespace | 53 } // namespace |
87 | 54 |
88 // static | 55 // static |
89 scoped_ptr<MessageHandler> MessageHandler::Create( | 56 scoped_ptr<MessageHandler> MessageHandler::Create( |
90 PP_Instance instance, | 57 PP_Instance instance, |
91 const PPP_MessageHandler_0_2* handler_if, | 58 const PPP_MessageHandler_0_2* handler_if, |
92 void* user_data, | 59 void* user_data, |
93 PP_Resource message_loop, | 60 PP_Resource message_loop, |
94 int32_t* error) { | 61 int32_t* error) { |
95 scoped_ptr<MessageHandler> result; | 62 scoped_ptr<MessageHandler> result; |
(...skipping 17 matching lines...) Expand all Loading... |
113 *error = PP_ERROR_WRONG_THREAD; | 80 *error = PP_ERROR_WRONG_THREAD; |
114 return result.Pass(); | 81 return result.Pass(); |
115 } | 82 } |
116 | 83 |
117 result.reset(new MessageHandler( | 84 result.reset(new MessageHandler( |
118 instance, handler_if, user_data, message_loop_resource)); | 85 instance, handler_if, user_data, message_loop_resource)); |
119 *error = PP_OK; | 86 *error = PP_OK; |
120 return result.Pass(); | 87 return result.Pass(); |
121 } | 88 } |
122 | 89 |
123 // CreateDeprecated is a near-exact copy of Create, but we'll just delete it | |
124 // when 0.1 is deprecated, so need to get fancy to avoid code duplication. | |
125 // TODO(dmichael) crbug.com/414398 | |
126 // static | |
127 scoped_ptr<MessageHandler> MessageHandler::CreateDeprecated( | |
128 PP_Instance instance, | |
129 const PPP_MessageHandler_0_1_Deprecated* handler_if, | |
130 void* user_data, | |
131 PP_Resource message_loop, | |
132 int32_t* error) { | |
133 scoped_ptr<MessageHandler> result; | |
134 // The interface and all function pointers must be valid. | |
135 if (!handler_if || | |
136 !handler_if->HandleMessage || | |
137 !handler_if->HandleBlockingMessage || | |
138 !handler_if->Destroy) { | |
139 *error = PP_ERROR_BADARGUMENT; | |
140 return result.Pass(); | |
141 } | |
142 thunk::EnterResourceNoLock<thunk::PPB_MessageLoop_API> | |
143 enter_loop(message_loop, true); | |
144 if (enter_loop.failed()) { | |
145 *error = PP_ERROR_BADRESOURCE; | |
146 return result.Pass(); | |
147 } | |
148 scoped_refptr<MessageLoopResource> message_loop_resource( | |
149 static_cast<MessageLoopResource*>(enter_loop.object())); | |
150 if (message_loop_resource->is_main_thread_loop()) { | |
151 *error = PP_ERROR_WRONG_THREAD; | |
152 return result.Pass(); | |
153 } | |
154 | |
155 result.reset(new MessageHandler( | |
156 instance, handler_if, user_data, message_loop_resource)); | |
157 *error = PP_OK; | |
158 return result.Pass(); | |
159 } | |
160 | |
161 MessageHandler::~MessageHandler() { | 90 MessageHandler::~MessageHandler() { |
162 // It's possible the message_loop_proxy is NULL if that loop has been quit. | 91 // It's possible the message_loop_proxy is NULL if that loop has been quit. |
163 // In that case, we unfortunately just can't call Destroy. | 92 // In that case, we unfortunately just can't call Destroy. |
164 if (message_loop_->message_loop_proxy().get()) { | 93 if (message_loop_->message_loop_proxy().get()) { |
165 // The posted task won't have the proxy lock, but that's OK, it doesn't | 94 // The posted task won't have the proxy lock, but that's OK, it doesn't |
166 // touch any internal state; it's a direct call on the plugin's function. | 95 // touch any internal state; it's a direct call on the plugin's function. |
167 if (handler_if_0_1_) { | |
168 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, | |
169 base::Bind(handler_if_0_1_->Destroy, | |
170 instance_, | |
171 user_data_)); | |
172 return; | |
173 } | |
174 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, | 96 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, |
175 base::Bind(handler_if_->Destroy, | 97 base::Bind(handler_if_->Destroy, |
176 instance_, | 98 instance_, |
177 user_data_)); | 99 user_data_)); |
178 } | 100 } |
179 } | 101 } |
180 | 102 |
181 bool MessageHandler::LoopIsValid() const { | 103 bool MessageHandler::LoopIsValid() const { |
182 return !!message_loop_->message_loop_proxy().get(); | 104 return !!message_loop_->message_loop_proxy().get(); |
183 } | 105 } |
184 | 106 |
185 void MessageHandler::HandleMessage(ScopedPPVar var) { | 107 void MessageHandler::HandleMessage(ScopedPPVar var) { |
186 if (handler_if_0_1_) { | |
187 // TODO(dmichael): Remove this code path. crbug.com/414398 | |
188 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, | |
189 RunWhileLocked(base::Bind(&HandleMessageWrapper_0_1, | |
190 handler_if_0_1_->HandleMessage, | |
191 instance_, | |
192 user_data_, | |
193 var))); | |
194 return; | |
195 } | |
196 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, | 108 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, |
197 RunWhileLocked(base::Bind(&HandleMessageWrapper, | 109 RunWhileLocked(base::Bind(&HandleMessageWrapper, |
198 handler_if_->HandleMessage, | 110 handler_if_->HandleMessage, |
199 instance_, | 111 instance_, |
200 user_data_, | 112 user_data_, |
201 var))); | 113 var))); |
202 } | 114 } |
203 | 115 |
204 void MessageHandler::HandleBlockingMessage(ScopedPPVar var, | 116 void MessageHandler::HandleBlockingMessage(ScopedPPVar var, |
205 scoped_ptr<IPC::Message> reply_msg) { | 117 scoped_ptr<IPC::Message> reply_msg) { |
206 if (handler_if_0_1_) { | |
207 // TODO(dmichael): Remove this code path. crbug.com/414398 | |
208 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, | |
209 RunWhileLocked(base::Bind(&HandleBlockingMessageWrapper_0_1, | |
210 handler_if_0_1_->HandleBlockingMessage, | |
211 instance_, | |
212 user_data_, | |
213 var, | |
214 base::Passed(reply_msg.Pass())))); | |
215 return; | |
216 } | |
217 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, | 118 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, |
218 RunWhileLocked(base::Bind(&HandleBlockingMessageWrapper, | 119 RunWhileLocked(base::Bind(&HandleBlockingMessageWrapper, |
219 handler_if_->HandleBlockingMessage, | 120 handler_if_->HandleBlockingMessage, |
220 instance_, | 121 instance_, |
221 user_data_, | 122 user_data_, |
222 var, | 123 var, |
223 base::Passed(reply_msg.Pass())))); | 124 base::Passed(reply_msg.Pass())))); |
224 } | 125 } |
225 | 126 |
226 MessageHandler::MessageHandler( | 127 MessageHandler::MessageHandler( |
227 PP_Instance instance, | 128 PP_Instance instance, |
228 const PPP_MessageHandler_0_2* handler_if, | 129 const PPP_MessageHandler_0_2* handler_if, |
229 void* user_data, | 130 void* user_data, |
230 scoped_refptr<MessageLoopResource> message_loop) | 131 scoped_refptr<MessageLoopResource> message_loop) |
231 : instance_(instance), | 132 : instance_(instance), |
232 handler_if_(handler_if), | 133 handler_if_(handler_if), |
233 handler_if_0_1_(NULL), | |
234 user_data_(user_data), | 134 user_data_(user_data), |
235 message_loop_(message_loop) { | 135 message_loop_(message_loop) { |
236 } | 136 } |
237 | |
238 MessageHandler::MessageHandler( | |
239 PP_Instance instance, | |
240 const PPP_MessageHandler_0_1_Deprecated* handler_if, | |
241 void* user_data, | |
242 scoped_refptr<MessageLoopResource> message_loop) | |
243 : instance_(instance), | |
244 handler_if_(NULL), | |
245 handler_if_0_1_(handler_if), | |
246 user_data_(user_data), | |
247 message_loop_(message_loop) { | |
248 } | |
249 | 137 |
250 } // namespace proxy | 138 } // namespace proxy |
251 } // namespace ppapi | 139 } // namespace ppapi |
OLD | NEW |