| 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 11 matching lines...) Expand all Loading... |
| 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebArrayBuffer.h" | 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebArrayBuffer.h" |
| 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
| 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" | 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" |
| 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" | 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" |
| 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSocket.h" | 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSocket.h" |
| 27 #include "webkit/plugins/ppapi/host_array_buffer_var.h" | 27 #include "webkit/plugins/ppapi/host_array_buffer_var.h" |
| 28 #include "webkit/plugins/ppapi/host_globals.h" | 28 #include "webkit/plugins/ppapi/host_globals.h" |
| 29 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 29 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
| 30 #include "webkit/plugins/ppapi/resource_helper.h" | 30 #include "webkit/plugins/ppapi/resource_helper.h" |
| 31 | 31 |
| 32 using ppapi::ApiCallbackType; |
| 32 using ppapi::ArrayBufferVar; | 33 using ppapi::ArrayBufferVar; |
| 33 using ppapi::PpapiGlobals; | 34 using ppapi::PpapiGlobals; |
| 34 using ppapi::StringVar; | 35 using ppapi::StringVar; |
| 35 using ppapi::thunk::PPB_WebSocket_API; | 36 using ppapi::thunk::PPB_WebSocket_API; |
| 36 using ppapi::TrackedCallback; | 37 using ppapi::TrackedCallback; |
| 37 using ppapi::Var; | 38 using ppapi::Var; |
| 38 using ppapi::VarTracker; | 39 using ppapi::VarTracker; |
| 39 using WebKit::WebArrayBuffer; | 40 using WebKit::WebArrayBuffer; |
| 40 using WebKit::WebDocument; | 41 using WebKit::WebDocument; |
| 41 using WebKit::WebString; | 42 using WebKit::WebString; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 return ws->GetReference(); | 101 return ws->GetReference(); |
| 101 } | 102 } |
| 102 | 103 |
| 103 PPB_WebSocket_API* PPB_WebSocket_Impl::AsPPB_WebSocket_API() { | 104 PPB_WebSocket_API* PPB_WebSocket_Impl::AsPPB_WebSocket_API() { |
| 104 return this; | 105 return this; |
| 105 } | 106 } |
| 106 | 107 |
| 107 int32_t PPB_WebSocket_Impl::Connect(PP_Var url, | 108 int32_t PPB_WebSocket_Impl::Connect(PP_Var url, |
| 108 const PP_Var protocols[], | 109 const PP_Var protocols[], |
| 109 uint32_t protocol_count, | 110 uint32_t protocol_count, |
| 110 PP_CompletionCallback callback) { | 111 ApiCallbackType callback) { |
| 111 // Check mandatory interfaces. | 112 // Check mandatory interfaces. |
| 112 PluginInstance* plugin_instance = ResourceHelper::GetPluginInstance(this); | 113 PluginInstance* plugin_instance = ResourceHelper::GetPluginInstance(this); |
| 113 DCHECK(plugin_instance); | 114 DCHECK(plugin_instance); |
| 114 if (!plugin_instance) | 115 if (!plugin_instance) |
| 115 return PP_ERROR_FAILED; | 116 return PP_ERROR_FAILED; |
| 116 | 117 |
| 117 // Connect() can be called at most once. | 118 // Connect() can be called at most once. |
| 118 if (websocket_.get()) | 119 if (websocket_.get()) |
| 119 return PP_ERROR_INPROGRESS; | 120 return PP_ERROR_INPROGRESS; |
| 120 if (state_ != PP_WEBSOCKETREADYSTATE_INVALID) | 121 if (state_ != PP_WEBSOCKETREADYSTATE_INVALID) |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 character == '{' || character == '}') | 175 character == '{' || character == '}') |
| 175 return PP_ERROR_BADARGUMENT; | 176 return PP_ERROR_BADARGUMENT; |
| 176 } | 177 } |
| 177 // Join protocols with the comma separator. | 178 // Join protocols with the comma separator. |
| 178 if (i != 0) | 179 if (i != 0) |
| 179 protocol_string.append(","); | 180 protocol_string.append(","); |
| 180 protocol_string.append(protocol->value()); | 181 protocol_string.append(protocol->value()); |
| 181 } | 182 } |
| 182 WebString web_protocols = WebString::fromUTF8(protocol_string); | 183 WebString web_protocols = WebString::fromUTF8(protocol_string); |
| 183 | 184 |
| 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. | 185 // Create WebKit::WebSocket object and connect. |
| 189 WebDocument document = plugin_instance->container()->element().document(); | 186 WebDocument document = plugin_instance->container()->element().document(); |
| 190 websocket_.reset(WebSocket::create(document, this)); | 187 websocket_.reset(WebSocket::create(document, this)); |
| 191 DCHECK(websocket_.get()); | 188 DCHECK(websocket_.get()); |
| 192 if (!websocket_.get()) | 189 if (!websocket_.get()) |
| 193 return PP_ERROR_NOTSUPPORTED; | 190 return PP_ERROR_NOTSUPPORTED; |
| 194 | 191 |
| 195 // Set receiving binary object type. | 192 // Set receiving binary object type. |
| 196 websocket_->setBinaryType(WebSocket::BinaryTypeArrayBuffer); | 193 websocket_->setBinaryType(WebSocket::BinaryTypeArrayBuffer); |
| 197 | 194 |
| 198 websocket_->connect(web_url, web_protocols); | 195 websocket_->connect(web_url, web_protocols); |
| 199 state_ = PP_WEBSOCKETREADYSTATE_CONNECTING; | 196 state_ = PP_WEBSOCKETREADYSTATE_CONNECTING; |
| 200 | 197 |
| 201 // Install callback. | 198 // Install callback. |
| 202 connect_callback_ = new TrackedCallback(this, callback); | 199 connect_callback_ = callback; |
| 203 | 200 |
| 204 return PP_OK_COMPLETIONPENDING; | 201 return PP_OK_COMPLETIONPENDING; |
| 205 } | 202 } |
| 206 | 203 |
| 207 int32_t PPB_WebSocket_Impl::Close(uint16_t code, | 204 int32_t PPB_WebSocket_Impl::Close(uint16_t code, |
| 208 PP_Var reason, | 205 PP_Var reason, |
| 209 PP_CompletionCallback callback) { | 206 ApiCallbackType callback) { |
| 210 // Check mandarory interfaces. | 207 // Check mandarory interfaces. |
| 211 if (!websocket_.get()) | 208 if (!websocket_.get()) |
| 212 return PP_ERROR_FAILED; | 209 return PP_ERROR_FAILED; |
| 213 | 210 |
| 214 // Validate |code|. Need to cast |CloseEventCodeNotSpecified| which is -1 to | 211 // Validate |code|. Need to cast |CloseEventCodeNotSpecified| which is -1 to |
| 215 // uint16_t for the comparison to work. | 212 // uint16_t for the comparison to work. |
| 216 if (code != static_cast<uint16_t>(WebSocket::CloseEventCodeNotSpecified)) { | 213 if (code != static_cast<uint16_t>(WebSocket::CloseEventCodeNotSpecified)) { |
| 217 if (!(code == WebSocket::CloseEventCodeNormalClosure || | 214 if (!(code == WebSocket::CloseEventCodeNormalClosure || |
| 218 (WebSocket::CloseEventCodeMinimumUserDefined <= code && | 215 (WebSocket::CloseEventCodeMinimumUserDefined <= code && |
| 219 code <= WebSocket::CloseEventCodeMaximumUserDefined))) | 216 code <= WebSocket::CloseEventCodeMaximumUserDefined))) |
| 220 // RFC 6455 limits applications to use reserved connection close code in | 217 // RFC 6455 limits applications to use reserved connection close code in |
| 221 // section 7.4.2.. The WebSocket API (http://www.w3.org/TR/websockets/) | 218 // section 7.4.2.. The WebSocket API (http://www.w3.org/TR/websockets/) |
| 222 // defines this out of range error as InvalidAccessError in JavaScript. | 219 // defines this out of range error as InvalidAccessError in JavaScript. |
| 223 return PP_ERROR_NOACCESS; | 220 return PP_ERROR_NOACCESS; |
| 224 } | 221 } |
| 225 | 222 |
| 226 // Validate |reason|. | 223 // Validate |reason|. |
| 227 // TODO(toyoshim): Returns PP_ERROR_BADARGUMENT if |reason| contains any | 224 // TODO(toyoshim): Returns PP_ERROR_BADARGUMENT if |reason| contains any |
| 228 // surrogates. | 225 // surrogates. |
| 229 scoped_refptr<StringVar> reason_string = StringVar::FromPPVar(reason); | 226 scoped_refptr<StringVar> reason_string = StringVar::FromPPVar(reason); |
| 230 if (!reason_string || reason_string->value().size() > kMaxReasonSizeInBytes) | 227 if (!reason_string || reason_string->value().size() > kMaxReasonSizeInBytes) |
| 231 return PP_ERROR_BADARGUMENT; | 228 return PP_ERROR_BADARGUMENT; |
| 232 | 229 |
| 233 // Check state. | 230 // Check state. |
| 234 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING || | 231 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING || |
| 235 state_ == PP_WEBSOCKETREADYSTATE_CLOSED) | 232 state_ == PP_WEBSOCKETREADYSTATE_CLOSED) |
| 236 return PP_ERROR_INPROGRESS; | 233 return PP_ERROR_INPROGRESS; |
| 237 | 234 |
| 238 // Validate |callback| (Doesn't support blocking callback) | |
| 239 if (!callback.func) | |
| 240 return PP_ERROR_BLOCKS_MAIN_THREAD; | |
| 241 | |
| 242 // Install |callback|. | 235 // Install |callback|. |
| 243 close_callback_ = new TrackedCallback(this, callback); | 236 close_callback_ = callback; |
| 244 | 237 |
| 245 // Abort ongoing connect. | 238 // Abort ongoing connect. |
| 246 if (state_ == PP_WEBSOCKETREADYSTATE_CONNECTING) { | 239 if (state_ == PP_WEBSOCKETREADYSTATE_CONNECTING) { |
| 247 state_ = PP_WEBSOCKETREADYSTATE_CLOSING; | 240 state_ = PP_WEBSOCKETREADYSTATE_CLOSING; |
| 248 // Need to do a "Post" to avoid reentering the plugin. | 241 // Need to do a "Post" to avoid reentering the plugin. |
| 249 connect_callback_->PostAbort(); | 242 connect_callback_->PostAbort(); |
| 250 connect_callback_ = NULL; | 243 connect_callback_ = NULL; |
| 251 websocket_->fail( | 244 websocket_->fail( |
| 252 "WebSocket was closed before the connection was established."); | 245 "WebSocket was closed before the connection was established."); |
| 253 return PP_OK_COMPLETIONPENDING; | 246 return PP_OK_COMPLETIONPENDING; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 265 | 258 |
| 266 // Close connection. | 259 // Close connection. |
| 267 state_ = PP_WEBSOCKETREADYSTATE_CLOSING; | 260 state_ = PP_WEBSOCKETREADYSTATE_CLOSING; |
| 268 WebString web_reason = WebString::fromUTF8(reason_string->value()); | 261 WebString web_reason = WebString::fromUTF8(reason_string->value()); |
| 269 websocket_->close(code, web_reason); | 262 websocket_->close(code, web_reason); |
| 270 | 263 |
| 271 return PP_OK_COMPLETIONPENDING; | 264 return PP_OK_COMPLETIONPENDING; |
| 272 } | 265 } |
| 273 | 266 |
| 274 int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, | 267 int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, |
| 275 PP_CompletionCallback callback) { | 268 ApiCallbackType callback) { |
| 276 // Check state. | 269 // Check state. |
| 277 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID || | 270 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID || |
| 278 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING) | 271 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING) |
| 279 return PP_ERROR_BADARGUMENT; | 272 return PP_ERROR_BADARGUMENT; |
| 280 | 273 |
| 281 // Just return received message if any received message is queued. | 274 // Just return received message if any received message is queued. |
| 282 if (!received_messages_.empty()) { | 275 if (!received_messages_.empty()) { |
| 283 receive_callback_var_ = message; | 276 receive_callback_var_ = message; |
| 284 return DoReceive(); | 277 return DoReceive(); |
| 285 } | 278 } |
| 286 | 279 |
| 287 // Check state again. In CLOSED state, no more messages will be received. | 280 // Check state again. In CLOSED state, no more messages will be received. |
| 288 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED) | 281 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED) |
| 289 return PP_ERROR_BADARGUMENT; | 282 return PP_ERROR_BADARGUMENT; |
| 290 | 283 |
| 291 // Returns PP_ERROR_FAILED after an error is received and received messages | 284 // Returns PP_ERROR_FAILED after an error is received and received messages |
| 292 // is exhausted. | 285 // is exhausted. |
| 293 if (error_was_received_) | 286 if (error_was_received_) |
| 294 return PP_ERROR_FAILED; | 287 return PP_ERROR_FAILED; |
| 295 | 288 |
| 296 // Validate |callback| (Doesn't support blocking callback) | |
| 297 if (!callback.func) | |
| 298 return PP_ERROR_BLOCKS_MAIN_THREAD; | |
| 299 | |
| 300 // Or retain |message| as buffer to store and install |callback|. | 289 // Or retain |message| as buffer to store and install |callback|. |
| 301 wait_for_receive_ = true; | 290 wait_for_receive_ = true; |
| 302 receive_callback_var_ = message; | 291 receive_callback_var_ = message; |
| 303 receive_callback_ = new TrackedCallback(this, callback); | 292 receive_callback_ = callback; |
| 304 | 293 |
| 305 return PP_OK_COMPLETIONPENDING; | 294 return PP_OK_COMPLETIONPENDING; |
| 306 } | 295 } |
| 307 | 296 |
| 308 int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) { | 297 int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) { |
| 309 // Check mandatory interfaces. | 298 // Check mandatory interfaces. |
| 310 if (!websocket_.get()) | 299 if (!websocket_.get()) |
| 311 return PP_ERROR_FAILED; | 300 return PP_ERROR_FAILED; |
| 312 | 301 |
| 313 // Check state. | 302 // Check state. |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 | 513 |
| 525 *receive_callback_var_ = received_messages_.front()->GetPPVar(); | 514 *receive_callback_var_ = received_messages_.front()->GetPPVar(); |
| 526 received_messages_.pop(); | 515 received_messages_.pop(); |
| 527 receive_callback_var_ = NULL; | 516 receive_callback_var_ = NULL; |
| 528 wait_for_receive_ = false; | 517 wait_for_receive_ = false; |
| 529 return PP_OK; | 518 return PP_OK; |
| 530 } | 519 } |
| 531 | 520 |
| 532 } // namespace ppapi | 521 } // namespace ppapi |
| 533 } // namespace webkit | 522 } // namespace webkit |
| OLD | NEW |