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 #include "webkit/plugins/ppapi/ppb_websocket_impl.h" | 5 #include "webkit/plugins/ppapi/ppb_websocket_impl.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 return ws->GetReference(); | 100 return ws->GetReference(); |
101 } | 101 } |
102 | 102 |
103 PPB_WebSocket_API* PPB_WebSocket_Impl::AsPPB_WebSocket_API() { | 103 PPB_WebSocket_API* PPB_WebSocket_Impl::AsPPB_WebSocket_API() { |
104 return this; | 104 return this; |
105 } | 105 } |
106 | 106 |
107 int32_t PPB_WebSocket_Impl::Connect(PP_Var url, | 107 int32_t PPB_WebSocket_Impl::Connect(PP_Var url, |
108 const PP_Var protocols[], | 108 const PP_Var protocols[], |
109 uint32_t protocol_count, | 109 uint32_t protocol_count, |
110 PP_CompletionCallback callback) { | 110 scoped_refptr<TrackedCallback> callback) { |
111 // Check mandatory interfaces. | 111 // Check mandatory interfaces. |
112 PluginInstance* plugin_instance = ResourceHelper::GetPluginInstance(this); | 112 PluginInstance* plugin_instance = ResourceHelper::GetPluginInstance(this); |
113 DCHECK(plugin_instance); | 113 DCHECK(plugin_instance); |
114 if (!plugin_instance) | 114 if (!plugin_instance) |
115 return PP_ERROR_FAILED; | 115 return PP_ERROR_FAILED; |
116 | 116 |
117 // Connect() can be called at most once. | 117 // Connect() can be called at most once. |
118 if (websocket_.get()) | 118 if (websocket_.get()) |
119 return PP_ERROR_INPROGRESS; | 119 return PP_ERROR_INPROGRESS; |
120 if (state_ != PP_WEBSOCKETREADYSTATE_INVALID) | 120 if (state_ != PP_WEBSOCKETREADYSTATE_INVALID) |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 character == '{' || character == '}') | 174 character == '{' || character == '}') |
175 return PP_ERROR_BADARGUMENT; | 175 return PP_ERROR_BADARGUMENT; |
176 } | 176 } |
177 // Join protocols with the comma separator. | 177 // Join protocols with the comma separator. |
178 if (i != 0) | 178 if (i != 0) |
179 protocol_string.append(","); | 179 protocol_string.append(","); |
180 protocol_string.append(protocol->value()); | 180 protocol_string.append(protocol->value()); |
181 } | 181 } |
182 WebString web_protocols = WebString::fromUTF8(protocol_string); | 182 WebString web_protocols = WebString::fromUTF8(protocol_string); |
183 | 183 |
184 // Validate |callback| (Doesn't support blocking callback) | |
185 if (!callback.func) | |
186 return PP_ERROR_BLOCKS_MAIN_THREAD; | |
187 | |
188 // Create WebKit::WebSocket object and connect. | 184 // Create WebKit::WebSocket object and connect. |
189 WebDocument document = plugin_instance->container()->element().document(); | 185 WebDocument document = plugin_instance->container()->element().document(); |
190 websocket_.reset(WebSocket::create(document, this)); | 186 websocket_.reset(WebSocket::create(document, this)); |
191 DCHECK(websocket_.get()); | 187 DCHECK(websocket_.get()); |
192 if (!websocket_.get()) | 188 if (!websocket_.get()) |
193 return PP_ERROR_NOTSUPPORTED; | 189 return PP_ERROR_NOTSUPPORTED; |
194 | 190 |
195 // Set receiving binary object type. | 191 // Set receiving binary object type. |
196 websocket_->setBinaryType(WebSocket::BinaryTypeArrayBuffer); | 192 websocket_->setBinaryType(WebSocket::BinaryTypeArrayBuffer); |
197 | 193 |
198 websocket_->connect(web_url, web_protocols); | 194 websocket_->connect(web_url, web_protocols); |
199 state_ = PP_WEBSOCKETREADYSTATE_CONNECTING; | 195 state_ = PP_WEBSOCKETREADYSTATE_CONNECTING; |
200 | 196 |
201 // Install callback. | 197 // Install callback. |
202 connect_callback_ = new TrackedCallback(this, callback); | 198 connect_callback_ = callback; |
203 | 199 |
204 return PP_OK_COMPLETIONPENDING; | 200 return PP_OK_COMPLETIONPENDING; |
205 } | 201 } |
206 | 202 |
207 int32_t PPB_WebSocket_Impl::Close(uint16_t code, | 203 int32_t PPB_WebSocket_Impl::Close(uint16_t code, |
208 PP_Var reason, | 204 PP_Var reason, |
209 PP_CompletionCallback callback) { | 205 scoped_refptr<TrackedCallback> callback) { |
210 // Check mandarory interfaces. | 206 // Check mandarory interfaces. |
211 if (!websocket_.get()) | 207 if (!websocket_.get()) |
212 return PP_ERROR_FAILED; | 208 return PP_ERROR_FAILED; |
213 | 209 |
214 // Validate |code|. Need to cast |CloseEventCodeNotSpecified| which is -1 to | 210 // Validate |code|. Need to cast |CloseEventCodeNotSpecified| which is -1 to |
215 // uint16_t for the comparison to work. | 211 // uint16_t for the comparison to work. |
216 if (code != static_cast<uint16_t>(WebSocket::CloseEventCodeNotSpecified)) { | 212 if (code != static_cast<uint16_t>(WebSocket::CloseEventCodeNotSpecified)) { |
217 if (!(code == WebSocket::CloseEventCodeNormalClosure || | 213 if (!(code == WebSocket::CloseEventCodeNormalClosure || |
218 (WebSocket::CloseEventCodeMinimumUserDefined <= code && | 214 (WebSocket::CloseEventCodeMinimumUserDefined <= code && |
219 code <= WebSocket::CloseEventCodeMaximumUserDefined))) | 215 code <= WebSocket::CloseEventCodeMaximumUserDefined))) |
(...skipping 14 matching lines...) Expand all Loading... |
234 return PP_ERROR_BADARGUMENT; | 230 return PP_ERROR_BADARGUMENT; |
235 web_reason = WebString::fromUTF8(reason_string->value()); | 231 web_reason = WebString::fromUTF8(reason_string->value()); |
236 } | 232 } |
237 | 233 |
238 // Check state. | 234 // Check state. |
239 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING) | 235 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING) |
240 return PP_ERROR_INPROGRESS; | 236 return PP_ERROR_INPROGRESS; |
241 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED) | 237 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED) |
242 return PP_OK; | 238 return PP_OK; |
243 | 239 |
244 // Validate |callback| (Doesn't support blocking callback) | |
245 if (!callback.func) | |
246 return PP_ERROR_BLOCKS_MAIN_THREAD; | |
247 | |
248 // Install |callback|. | 240 // Install |callback|. |
249 close_callback_ = new TrackedCallback(this, callback); | 241 close_callback_ = callback; |
250 | 242 |
251 // Abort ongoing connect. | 243 // Abort ongoing connect. |
252 if (state_ == PP_WEBSOCKETREADYSTATE_CONNECTING) { | 244 if (state_ == PP_WEBSOCKETREADYSTATE_CONNECTING) { |
253 state_ = PP_WEBSOCKETREADYSTATE_CLOSING; | 245 state_ = PP_WEBSOCKETREADYSTATE_CLOSING; |
254 // Need to do a "Post" to avoid reentering the plugin. | 246 // Need to do a "Post" to avoid reentering the plugin. |
255 connect_callback_->PostAbort(); | 247 connect_callback_->PostAbort(); |
256 connect_callback_ = NULL; | 248 connect_callback_ = NULL; |
257 websocket_->fail( | 249 websocket_->fail( |
258 "WebSocket was closed before the connection was established."); | 250 "WebSocket was closed before the connection was established."); |
259 return PP_OK_COMPLETIONPENDING; | 251 return PP_OK_COMPLETIONPENDING; |
260 } | 252 } |
261 | 253 |
262 // Abort ongoing receive. | 254 // Abort ongoing receive. |
263 if (wait_for_receive_) { | 255 if (wait_for_receive_) { |
264 wait_for_receive_ = false; | 256 wait_for_receive_ = false; |
265 receive_callback_var_ = NULL; | 257 receive_callback_var_ = NULL; |
266 | 258 |
267 // Need to do a "Post" to avoid reentering the plugin. | 259 // Need to do a "Post" to avoid reentering the plugin. |
268 receive_callback_->PostAbort(); | 260 receive_callback_->PostAbort(); |
269 receive_callback_ = NULL; | 261 receive_callback_ = NULL; |
270 } | 262 } |
271 | 263 |
272 // Close connection. | 264 // Close connection. |
273 state_ = PP_WEBSOCKETREADYSTATE_CLOSING; | 265 state_ = PP_WEBSOCKETREADYSTATE_CLOSING; |
274 websocket_->close(code, web_reason); | 266 websocket_->close(code, web_reason); |
275 | 267 |
276 return PP_OK_COMPLETIONPENDING; | 268 return PP_OK_COMPLETIONPENDING; |
277 } | 269 } |
278 | 270 |
279 int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, | 271 int32_t PPB_WebSocket_Impl::ReceiveMessage( |
280 PP_CompletionCallback callback) { | 272 PP_Var* message, |
| 273 scoped_refptr<TrackedCallback> callback) { |
281 // Check state. | 274 // Check state. |
282 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID || | 275 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID || |
283 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING) | 276 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING) |
284 return PP_ERROR_BADARGUMENT; | 277 return PP_ERROR_BADARGUMENT; |
285 | 278 |
286 // Just return received message if any received message is queued. | 279 // Just return received message if any received message is queued. |
287 if (!received_messages_.empty()) { | 280 if (!received_messages_.empty()) { |
288 receive_callback_var_ = message; | 281 receive_callback_var_ = message; |
289 return DoReceive(); | 282 return DoReceive(); |
290 } | 283 } |
291 | 284 |
292 // Check state again. In CLOSED state, no more messages will be received. | 285 // Check state again. In CLOSED state, no more messages will be received. |
293 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED) | 286 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED) |
294 return PP_ERROR_BADARGUMENT; | 287 return PP_ERROR_BADARGUMENT; |
295 | 288 |
296 // Returns PP_ERROR_FAILED after an error is received and received messages | 289 // Returns PP_ERROR_FAILED after an error is received and received messages |
297 // is exhausted. | 290 // is exhausted. |
298 if (error_was_received_) | 291 if (error_was_received_) |
299 return PP_ERROR_FAILED; | 292 return PP_ERROR_FAILED; |
300 | 293 |
301 // Validate |callback| (Doesn't support blocking callback) | |
302 if (!callback.func) | |
303 return PP_ERROR_BLOCKS_MAIN_THREAD; | |
304 | |
305 // Or retain |message| as buffer to store and install |callback|. | 294 // Or retain |message| as buffer to store and install |callback|. |
306 wait_for_receive_ = true; | 295 wait_for_receive_ = true; |
307 receive_callback_var_ = message; | 296 receive_callback_var_ = message; |
308 receive_callback_ = new TrackedCallback(this, callback); | 297 receive_callback_ = callback; |
309 | 298 |
310 return PP_OK_COMPLETIONPENDING; | 299 return PP_OK_COMPLETIONPENDING; |
311 } | 300 } |
312 | 301 |
313 int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) { | 302 int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) { |
314 // Check mandatory interfaces. | 303 // Check mandatory interfaces. |
315 if (!websocket_.get()) | 304 if (!websocket_.get()) |
316 return PP_ERROR_FAILED; | 305 return PP_ERROR_FAILED; |
317 | 306 |
318 // Check state. | 307 // Check state. |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 | 518 |
530 *receive_callback_var_ = received_messages_.front()->GetPPVar(); | 519 *receive_callback_var_ = received_messages_.front()->GetPPVar(); |
531 received_messages_.pop(); | 520 received_messages_.pop(); |
532 receive_callback_var_ = NULL; | 521 receive_callback_var_ = NULL; |
533 wait_for_receive_ = false; | 522 wait_for_receive_ = false; |
534 return PP_OK; | 523 return PP_OK; |
535 } | 524 } |
536 | 525 |
537 } // namespace ppapi | 526 } // namespace ppapi |
538 } // namespace webkit | 527 } // namespace webkit |
OLD | NEW |