| 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 |