Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 return 0; | 57 return 0; |
| 58 | 58 |
| 59 uint64_t overhead = kHybiBaseFramingOverhead + kHybiMaskingKeyLength; | 59 uint64_t overhead = kHybiBaseFramingOverhead + kHybiMaskingKeyLength; |
| 60 if (payload_size > kMinimumPayloadSizeWithEightByteExtendedPayloadLength) | 60 if (payload_size > kMinimumPayloadSizeWithEightByteExtendedPayloadLength) |
| 61 overhead += 8; | 61 overhead += 8; |
| 62 else if (payload_size > kMinimumPayloadSizeWithTwoByteExtendedPayloadLength) | 62 else if (payload_size > kMinimumPayloadSizeWithTwoByteExtendedPayloadLength) |
| 63 overhead += 2; | 63 overhead += 2; |
| 64 return SaturateAdd(payload_size, overhead); | 64 return SaturateAdd(payload_size, overhead); |
| 65 } | 65 } |
| 66 | 66 |
| 67 bool InValidStateToReceive(PP_WebSocketReadyState_Dev state) { | |
| 68 if (state != PP_WEBSOCKETREADYSTATE_OPEN_DEV && | |
| 69 state != PP_WEBSOCKETREADYSTATE_CLOSING_DEV) | |
| 70 return false; | |
| 71 return true; | |
|
dmichael (off chromium)
2011/12/02 16:28:09
suggestion/nit: could also have just been:
return
Takashi Toyoshima
2011/12/02 17:15:42
Sounds good.
Fixed.
| |
| 72 } | |
| 73 | |
| 67 } // namespace | 74 } // namespace |
| 68 | 75 |
| 69 namespace webkit { | 76 namespace webkit { |
| 70 namespace ppapi { | 77 namespace ppapi { |
| 71 | 78 |
| 72 PPB_WebSocket_Impl::PPB_WebSocket_Impl(PP_Instance instance) | 79 PPB_WebSocket_Impl::PPB_WebSocket_Impl(PP_Instance instance) |
| 73 : Resource(instance), | 80 : Resource(instance), |
| 74 state_(PP_WEBSOCKETREADYSTATE_INVALID_DEV), | 81 state_(PP_WEBSOCKETREADYSTATE_INVALID_DEV), |
| 82 error_was_received_(false), | |
| 75 receive_callback_var_(NULL), | 83 receive_callback_var_(NULL), |
| 76 wait_for_receive_(false), | 84 wait_for_receive_(false), |
| 77 close_code_(0), | 85 close_code_(0), |
| 78 close_was_clean_(PP_FALSE), | 86 close_was_clean_(PP_FALSE), |
| 79 buffered_amount_(0), | 87 buffered_amount_(0), |
| 80 buffered_amount_after_close_(0) { | 88 buffered_amount_after_close_(0) { |
| 81 empty_string_ = new StringVar( | 89 empty_string_ = new StringVar( |
| 82 PpapiGlobals::Get()->GetModuleForInstance(instance), "", 0); | 90 PpapiGlobals::Get()->GetModuleForInstance(instance), "", 0); |
| 83 } | 91 } |
| 84 | 92 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 242 return PP_OK_COMPLETIONPENDING; | 250 return PP_OK_COMPLETIONPENDING; |
| 243 } | 251 } |
| 244 | 252 |
| 245 int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, | 253 int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, |
| 246 PP_CompletionCallback callback) { | 254 PP_CompletionCallback callback) { |
| 247 // Check state. | 255 // Check state. |
| 248 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV || | 256 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV || |
| 249 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) | 257 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) |
| 250 return PP_ERROR_BADARGUMENT; | 258 return PP_ERROR_BADARGUMENT; |
| 251 | 259 |
| 260 // Validate |callback| (Doesn't support blocking callback) | |
| 261 if (!callback.func) | |
| 262 return PP_ERROR_BLOCKS_MAIN_THREAD; | |
| 263 | |
| 252 // Just return received message if any received message is queued. | 264 // Just return received message if any received message is queued. |
| 253 if (!received_messages_.empty()) | 265 if (!received_messages_.empty()) |
| 254 return DoReceive(); | 266 return DoReceive(); |
| 255 | 267 |
| 268 // Returns PP_ERROR_FAILED after an error is received and received messages | |
| 269 // is exhausted. | |
| 270 if (error_was_received_) | |
| 271 return PP_ERROR_FAILED; | |
| 272 | |
| 256 // Or retain |message| as buffer to store and install |callback|. | 273 // Or retain |message| as buffer to store and install |callback|. |
| 257 wait_for_receive_ = true; | 274 wait_for_receive_ = true; |
| 258 receive_callback_var_ = message; | 275 receive_callback_var_ = message; |
| 259 receive_callback_ = callback; | 276 receive_callback_ = callback; |
| 260 | 277 |
| 261 return PP_OK_COMPLETIONPENDING; | 278 return PP_OK_COMPLETIONPENDING; |
| 262 } | 279 } |
| 263 | 280 |
| 264 int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) { | 281 int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) { |
| 265 // Check mandatory interfaces. | 282 // Check mandatory interfaces. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 350 return url_->GetPPVar(); | 367 return url_->GetPPVar(); |
| 351 } | 368 } |
| 352 | 369 |
| 353 void PPB_WebSocket_Impl::didConnect() { | 370 void PPB_WebSocket_Impl::didConnect() { |
| 354 DCHECK_EQ(PP_WEBSOCKETREADYSTATE_CONNECTING_DEV, state_); | 371 DCHECK_EQ(PP_WEBSOCKETREADYSTATE_CONNECTING_DEV, state_); |
| 355 state_ = PP_WEBSOCKETREADYSTATE_OPEN_DEV; | 372 state_ = PP_WEBSOCKETREADYSTATE_OPEN_DEV; |
| 356 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); | 373 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); |
| 357 } | 374 } |
| 358 | 375 |
| 359 void PPB_WebSocket_Impl::didReceiveMessage(const WebString& message) { | 376 void PPB_WebSocket_Impl::didReceiveMessage(const WebString& message) { |
| 377 // Dispose packets after receiving an error or in invalid state. | |
| 378 if (error_was_received_ || !InValidStateToReceive(state_)) | |
| 379 return; | |
| 380 | |
| 360 // Append received data to queue. | 381 // Append received data to queue. |
| 361 std::string string = message.utf8(); | 382 std::string string = message.utf8(); |
| 362 PP_Var var = StringVar::StringToPPVar( | 383 PP_Var var = StringVar::StringToPPVar( |
| 363 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), string); | 384 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), string); |
| 364 received_messages_.push(var); | 385 received_messages_.push(var); |
| 365 | 386 |
| 366 if (!wait_for_receive_) | 387 if (!wait_for_receive_) |
| 367 return; | 388 return; |
| 368 | 389 |
| 369 PP_RunAndClearCompletionCallback(&receive_callback_, DoReceive()); | 390 PP_RunAndClearCompletionCallback(&receive_callback_, DoReceive()); |
| 370 } | 391 } |
| 371 | 392 |
| 372 void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) { | 393 void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) { |
| 394 // Dispose packets after receiving an error or in invalid state. | |
| 395 if (error_was_received_ || !InValidStateToReceive(state_)) | |
| 396 return; | |
| 397 | |
| 398 // TODO(toyoshim): Support to receive binary data. | |
| 373 DLOG(INFO) << "didReceiveBinaryData is not implemented yet."; | 399 DLOG(INFO) << "didReceiveBinaryData is not implemented yet."; |
| 374 // TODO(toyoshim): Support to receive binary data. | |
| 375 } | 400 } |
| 376 | 401 |
| 377 void PPB_WebSocket_Impl::didReceiveMessageError() { | 402 void PPB_WebSocket_Impl::didReceiveMessageError() { |
| 378 // TODO(toyoshim): Must implement. | 403 // Ignore error notification in invalid state. |
| 379 DLOG(INFO) << "didReceiveMessageError is not implemented yet."; | 404 if (!InValidStateToReceive(state_)) |
| 405 return; | |
| 406 | |
| 407 // Records the error, then stops receiving any frames after this error. | |
| 408 // The error will be notified after all queued messages are read via | |
| 409 // ReceiveMessage(). | |
| 410 error_was_received_ = true; | |
| 411 if (!wait_for_receive_) | |
| 412 return; | |
| 413 | |
| 414 // But, if no messages is queued and ReceiveMessage() is now on going. | |
|
dmichael (off chromium)
2011/12/02 16:28:09
nit: is -> are
Takashi Toyoshima
2011/12/02 17:15:42
Done.
| |
| 415 // We must invoke the callback with error code here. | |
| 416 wait_for_receive_ = false; | |
| 417 PP_RunAndClearCompletionCallback(&receive_callback_, PP_ERROR_FAILED); | |
| 380 } | 418 } |
| 381 | 419 |
| 382 void PPB_WebSocket_Impl::didUpdateBufferedAmount( | 420 void PPB_WebSocket_Impl::didUpdateBufferedAmount( |
| 383 unsigned long buffered_amount) { | 421 unsigned long buffered_amount) { |
| 384 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) | 422 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) |
| 385 return; | 423 return; |
| 386 buffered_amount_ = buffered_amount; | 424 buffered_amount_ = buffered_amount; |
| 387 } | 425 } |
| 388 | 426 |
| 389 void PPB_WebSocket_Impl::didStartClosingHandshake() { | 427 void PPB_WebSocket_Impl::didStartClosingHandshake() { |
| 390 // TODO(toyoshim): Must implement. | 428 state_ = PP_WEBSOCKETREADYSTATE_CLOSING_DEV; |
| 391 DLOG(INFO) << "didStartClosingHandshake is not implemented yet."; | |
| 392 } | 429 } |
| 393 | 430 |
| 394 void PPB_WebSocket_Impl::didClose(unsigned long buffered_amount, | 431 void PPB_WebSocket_Impl::didClose(unsigned long unhandled_buffered_amount, |
| 395 ClosingHandshakeCompletionStatus status, | 432 ClosingHandshakeCompletionStatus status, |
| 396 unsigned short code, | 433 unsigned short code, |
| 397 const WebString& reason) { | 434 const WebString& reason) { |
| 398 // Store code and reason. | 435 // Store code and reason. |
| 399 close_code_ = code; | 436 close_code_ = code; |
| 400 std::string reason_string = reason.utf8(); | 437 std::string reason_string = reason.utf8(); |
| 401 close_reason_ = new StringVar( | 438 close_reason_ = new StringVar( |
| 402 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), reason_string); | 439 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), reason_string); |
| 403 | 440 |
| 404 // TODO(toyoshim): Set close_was_clean_. | 441 // Set close_was_clean_. |
| 442 bool was_clean = | |
| 443 state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV && | |
| 444 !unhandled_buffered_amount && | |
| 445 status == WebSocketClient::ClosingHandshakeComplete; | |
| 446 close_was_clean_ = was_clean ? PP_TRUE : PP_FALSE; | |
| 447 | |
| 448 // Update buffered_amount_. | |
| 449 buffered_amount_ = unhandled_buffered_amount; | |
| 405 | 450 |
| 406 // Handle state transition and invoking callback. | 451 // Handle state transition and invoking callback. |
| 407 DCHECK_NE(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, state_); | 452 DCHECK_NE(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, state_); |
| 408 PP_WebSocketReadyState_Dev state = state_; | 453 PP_WebSocketReadyState_Dev state = state_; |
| 409 state_ = PP_WEBSOCKETREADYSTATE_CLOSED_DEV; | 454 state_ = PP_WEBSOCKETREADYSTATE_CLOSED_DEV; |
| 410 | 455 |
| 411 // Update buffered_amount_. | |
| 412 buffered_amount_ = buffered_amount; | |
| 413 | |
| 414 if (state == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) | 456 if (state == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) |
| 415 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); | 457 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); |
| 416 | 458 |
| 417 if (state == PP_WEBSOCKETREADYSTATE_CLOSING_DEV) | 459 if (state == PP_WEBSOCKETREADYSTATE_CLOSING_DEV) |
| 418 PP_RunAndClearCompletionCallback(&close_callback_, PP_OK); | 460 PP_RunAndClearCompletionCallback(&close_callback_, PP_OK); |
| 461 | |
| 462 // Disconnect. | |
| 463 if (websocket_.get()) | |
| 464 websocket_->disconnect(); | |
| 419 } | 465 } |
| 420 | 466 |
| 421 int32_t PPB_WebSocket_Impl::DoReceive() { | 467 int32_t PPB_WebSocket_Impl::DoReceive() { |
| 422 // TODO(toyoshim): Check state. | |
| 423 | |
| 424 if (!receive_callback_var_) | 468 if (!receive_callback_var_) |
| 425 return PP_OK; | 469 return PP_OK; |
| 426 | 470 |
| 427 *receive_callback_var_ = received_messages_.front(); | 471 *receive_callback_var_ = received_messages_.front(); |
| 428 received_messages_.pop(); | 472 received_messages_.pop(); |
| 429 receive_callback_var_ = NULL; | 473 receive_callback_var_ = NULL; |
| 430 wait_for_receive_ = false; | 474 wait_for_receive_ = false; |
| 431 return PP_OK; | 475 return PP_OK; |
| 432 } | 476 } |
| 433 | 477 |
| 434 } // namespace ppapi | 478 } // namespace ppapi |
| 435 } // namespace webkit | 479 } // namespace webkit |
| OLD | NEW |