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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 65 } | 65 } |
| 66 | 66 |
| 67 } // namespace | 67 } // namespace |
| 68 | 68 |
| 69 namespace webkit { | 69 namespace webkit { |
| 70 namespace ppapi { | 70 namespace ppapi { |
| 71 | 71 |
| 72 PPB_WebSocket_Impl::PPB_WebSocket_Impl(PP_Instance instance) | 72 PPB_WebSocket_Impl::PPB_WebSocket_Impl(PP_Instance instance) |
| 73 : Resource(instance), | 73 : Resource(instance), |
| 74 state_(PP_WEBSOCKETREADYSTATE_INVALID_DEV), | 74 state_(PP_WEBSOCKETREADYSTATE_INVALID_DEV), |
| 75 error_was_received_(false), | |
| 75 receive_callback_var_(NULL), | 76 receive_callback_var_(NULL), |
| 76 wait_for_receive_(false), | 77 wait_for_receive_(false), |
| 77 close_code_(0), | 78 close_code_(0), |
| 78 close_was_clean_(PP_FALSE), | 79 close_was_clean_(PP_FALSE), |
| 79 buffered_amount_(0), | 80 buffered_amount_(0), |
| 80 buffered_amount_after_close_(0) { | 81 buffered_amount_after_close_(0) { |
| 81 empty_string_ = new StringVar( | 82 empty_string_ = new StringVar( |
| 82 PpapiGlobals::Get()->GetModuleForInstance(instance), "", 0); | 83 PpapiGlobals::Get()->GetModuleForInstance(instance), "", 0); |
| 83 } | 84 } |
| 84 | 85 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 websocket_->close(code, web_reason); | 244 websocket_->close(code, web_reason); |
| 244 | 245 |
| 245 return PP_OK_COMPLETIONPENDING; | 246 return PP_OK_COMPLETIONPENDING; |
| 246 } | 247 } |
| 247 | 248 |
| 248 int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, | 249 int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, |
| 249 PP_CompletionCallback callback) { | 250 PP_CompletionCallback callback) { |
| 250 // Check state. | 251 // Check state. |
| 251 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV || | 252 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV || |
| 252 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) | 253 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) |
| 253 return PP_ERROR_BADARGUMENT; | 254 return PP_ERROR_BADARGUMENT; |
|
dmichael (off chromium)
2011/12/01 17:09:34
Whoops, shouldn't this function also check that th
Takashi Toyoshima
2011/12/02 05:51:28
Oh, right!
I fix in the next change.
dmichael (off chromium)
2011/12/02 16:28:08
Okay. By the way, this one will be a little more s
Takashi Toyoshima
2011/12/02 17:15:42
OK, I verify callbacks just before install them to
| |
| 254 | 255 |
| 255 // Just return received message if any received message is queued. | 256 // Just return received message if any received message is queued. |
| 256 if (!received_messages_.empty()) | 257 if (!received_messages_.empty()) |
| 257 return DoReceive(); | 258 return DoReceive(); |
|
dmichael (off chromium)
2011/12/02 16:28:08
I just realized there's a problem here; you're not
Takashi Toyoshima
2011/12/02 17:15:42
Oh, I see.
I fix it.
| |
| 258 | 259 |
| 260 // Returns PP_ERROR_FAILED after an error is received and received messages | |
| 261 // is exhausted. | |
| 262 if (error_was_received_) | |
| 263 return PP_ERROR_FAILED; | |
| 264 | |
| 259 // Or retain |message| as buffer to store and install |callback|. | 265 // Or retain |message| as buffer to store and install |callback|. |
| 260 wait_for_receive_ = true; | 266 wait_for_receive_ = true; |
| 261 receive_callback_var_ = message; | 267 receive_callback_var_ = message; |
| 262 receive_callback_ = callback; | 268 receive_callback_ = callback; |
| 263 | 269 |
| 264 return PP_OK_COMPLETIONPENDING; | 270 return PP_OK_COMPLETIONPENDING; |
| 265 } | 271 } |
| 266 | 272 |
| 267 int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) { | 273 int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) { |
| 268 // Check mandatory interfaces. | 274 // Check mandatory interfaces. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 353 return url_->GetPPVar(); | 359 return url_->GetPPVar(); |
| 354 } | 360 } |
| 355 | 361 |
| 356 void PPB_WebSocket_Impl::didConnect() { | 362 void PPB_WebSocket_Impl::didConnect() { |
| 357 DCHECK_EQ(PP_WEBSOCKETREADYSTATE_CONNECTING_DEV, state_); | 363 DCHECK_EQ(PP_WEBSOCKETREADYSTATE_CONNECTING_DEV, state_); |
| 358 state_ = PP_WEBSOCKETREADYSTATE_OPEN_DEV; | 364 state_ = PP_WEBSOCKETREADYSTATE_OPEN_DEV; |
| 359 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); | 365 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); |
| 360 } | 366 } |
| 361 | 367 |
| 362 void PPB_WebSocket_Impl::didReceiveMessage(const WebString& message) { | 368 void PPB_WebSocket_Impl::didReceiveMessage(const WebString& message) { |
| 369 // Dispose packets after receiving an error. | |
| 370 if (error_was_received_) | |
| 371 return; | |
| 372 | |
| 373 // Dispose packets in invalid state. | |
| 374 if (state_ != PP_WEBSOCKETREADYSTATE_OPEN_DEV && | |
| 375 state_ != PP_WEBSOCKETREADYSTATE_CLOSING) | |
|
dmichael (off chromium)
2011/12/01 17:09:34
Shouldn't that be 'CLOSING_DEV'? In my local check
Takashi Toyoshima
2011/12/02 05:51:28
Yes!
Sorry, I missed compilation error?
Fixed.
| |
| 376 return; | |
| 377 | |
| 363 // Append received data to queue. | 378 // Append received data to queue. |
| 364 std::string string = message.utf8(); | 379 std::string string = message.utf8(); |
| 365 PP_Var var = StringVar::StringToPPVar( | 380 PP_Var var = StringVar::StringToPPVar( |
| 366 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), string); | 381 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), string); |
| 367 received_messages_.push(var); | 382 received_messages_.push(var); |
| 368 | 383 |
| 369 if (!wait_for_receive_) | 384 if (!wait_for_receive_) |
| 370 return; | 385 return; |
| 371 | 386 |
| 372 PP_RunAndClearCompletionCallback(&receive_callback_, DoReceive()); | 387 PP_RunAndClearCompletionCallback(&receive_callback_, DoReceive()); |
| 373 } | 388 } |
| 374 | 389 |
| 375 void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) { | 390 void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) { |
| 391 // Dispose packets after receiving an error. | |
| 392 if (error_was_received_) | |
| 393 return; | |
| 394 | |
| 395 // Dispose packets in invalid state. | |
| 396 if (state_ != PP_WEBSOCKETREADYSTATE_OPEN_DEV && | |
| 397 state_ != PP_WEBSOCKETREADYSTATE_CLOSING) | |
|
dmichael (off chromium)
2011/12/01 17:09:34
optional suggestion: You do this check a lot. It c
Takashi Toyoshima
2011/12/02 05:51:28
Sounds nice.
Done.
| |
| 398 return; | |
| 399 | |
| 400 // TODO(toyoshim): Support to receive binary data. | |
| 376 DLOG(INFO) << "didReceiveBinaryData is not implemented yet."; | 401 DLOG(INFO) << "didReceiveBinaryData is not implemented yet."; |
| 377 // TODO(toyoshim): Support to receive binary data. | |
| 378 } | 402 } |
| 379 | 403 |
| 380 void PPB_WebSocket_Impl::didReceiveMessageError() { | 404 void PPB_WebSocket_Impl::didReceiveMessageError() { |
| 381 // TODO(toyoshim): Must implement. | 405 if (state_ != PP_WEBSOCKETREADYSTATE_OPEN_DEV && |
| 382 DLOG(INFO) << "didReceiveMessageError is not implemented yet."; | 406 state_ != PP_WEBSOCKETREADYSTATE_CLOSING_DEV) |
| 407 return; | |
| 408 | |
| 409 // Pepper binding has no event or callback mechanism for errors. | |
|
dmichael (off chromium)
2011/12/01 17:09:34
I'm not sure I understand your comment. The idea d
Takashi Toyoshima
2011/12/02 05:51:28
didReceiveMessageError() callback was invoked from
| |
| 410 // Just remember the error, and notice after reading the last message as | |
| 411 // returned error code. | |
| 412 error_was_received_ = true; | |
| 413 | |
| 414 if (!wait_for_receive_) | |
| 415 return; | |
| 416 | |
| 417 // |received_messages| is empty and receiving process is on going. Received | |
| 418 // messages after an error is just ignored. So we must abort here. | |
| 419 wait_for_receive_ = false; | |
| 420 PP_RunAndClearCompletionCallback(&receive_callback_, PP_ERROR_FAILED); | |
|
dmichael (off chromium)
2011/12/01 17:09:34
Are you guaranteed that you'll still get 'didClose
Takashi Toyoshima
2011/12/02 05:51:28
all didReceiveMessageError() was followed by didCl
| |
| 383 } | 421 } |
| 384 | 422 |
| 385 void PPB_WebSocket_Impl::didUpdateBufferedAmount( | 423 void PPB_WebSocket_Impl::didUpdateBufferedAmount( |
| 386 unsigned long buffered_amount) { | 424 unsigned long buffered_amount) { |
| 387 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) | 425 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) |
| 388 return; | 426 return; |
| 389 buffered_amount_ = buffered_amount; | 427 buffered_amount_ = buffered_amount; |
| 390 } | 428 } |
| 391 | 429 |
| 392 void PPB_WebSocket_Impl::didStartClosingHandshake() { | 430 void PPB_WebSocket_Impl::didStartClosingHandshake() { |
| 393 // TODO(toyoshim): Must implement. | 431 state_ = PP_WEBSOCKETREADYSTATE_CLOSING_DEV; |
| 394 DLOG(INFO) << "didStartClosingHandshake is not implemented yet."; | |
| 395 } | 432 } |
| 396 | 433 |
| 397 void PPB_WebSocket_Impl::didClose(unsigned long buffered_amount, | 434 void PPB_WebSocket_Impl::didClose(unsigned long unhandled_buffered_amount, |
| 398 ClosingHandshakeCompletionStatus status, | 435 ClosingHandshakeCompletionStatus status, |
| 399 unsigned short code, | 436 unsigned short code, |
| 400 const WebString& reason) { | 437 const WebString& reason) { |
| 401 // Store code and reason. | 438 // Store code and reason. |
| 402 close_code_ = code; | 439 close_code_ = code; |
| 403 std::string reason_string = reason.utf8(); | 440 std::string reason_string = reason.utf8(); |
| 404 close_reason_ = new StringVar( | 441 close_reason_ = new StringVar( |
| 405 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), reason_string); | 442 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), reason_string); |
| 406 | 443 |
| 407 // TODO(toyoshim): Set close_was_clean_. | 444 // Set close_was_clean_. |
| 445 bool was_clean = | |
| 446 state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV && | |
| 447 !unhandled_buffered_amount && | |
| 448 status == WebSocketClient::ClosingHandshakeComplete; | |
| 449 close_was_clean_ = was_clean ? PP_TRUE : PP_FALSE; | |
| 450 | |
| 451 // Update buffered_amount_. | |
| 452 buffered_amount_ = unhandled_buffered_amount; | |
| 408 | 453 |
| 409 // Handle state transition and invoking callback. | 454 // Handle state transition and invoking callback. |
| 410 DCHECK_NE(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, state_); | 455 DCHECK_NE(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, state_); |
| 411 PP_WebSocketReadyState_Dev state = state_; | 456 PP_WebSocketReadyState_Dev state = state_; |
| 412 state_ = PP_WEBSOCKETREADYSTATE_CLOSED_DEV; | 457 state_ = PP_WEBSOCKETREADYSTATE_CLOSED_DEV; |
| 413 | 458 |
| 414 // Update buffered_amount_. | |
| 415 buffered_amount_ = buffered_amount; | |
| 416 | |
| 417 if (state == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) | 459 if (state == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) |
| 418 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); | 460 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); |
| 419 | 461 |
| 420 if (state == PP_WEBSOCKETREADYSTATE_CLOSING_DEV) | 462 if (state == PP_WEBSOCKETREADYSTATE_CLOSING_DEV) |
| 421 PP_RunAndClearCompletionCallback(&close_callback_, PP_OK); | 463 PP_RunAndClearCompletionCallback(&close_callback_, PP_OK); |
| 464 | |
| 465 // Disconnect. | |
| 466 if (websocket_.get()) | |
| 467 websocket_->disconnect(); | |
| 422 } | 468 } |
| 423 | 469 |
| 424 int32_t PPB_WebSocket_Impl::DoReceive() { | 470 int32_t PPB_WebSocket_Impl::DoReceive() { |
| 425 // TODO(toyoshim): Check state. | |
| 426 | |
| 427 if (!receive_callback_var_) | 471 if (!receive_callback_var_) |
| 428 return PP_OK; | 472 return PP_OK; |
| 429 | 473 |
| 430 *receive_callback_var_ = received_messages_.front(); | 474 *receive_callback_var_ = received_messages_.front(); |
| 431 received_messages_.pop(); | 475 received_messages_.pop(); |
| 432 receive_callback_var_ = NULL; | 476 receive_callback_var_ = NULL; |
| 433 wait_for_receive_ = false; | 477 wait_for_receive_ = false; |
| 434 return PP_OK; | 478 return PP_OK; |
| 435 } | 479 } |
| 436 | 480 |
| 437 } // namespace ppapi | 481 } // namespace ppapi |
| 438 } // namespace webkit | 482 } // namespace webkit |
| OLD | NEW |