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" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "googleurl/src/gurl.h" | 12 #include "googleurl/src/gurl.h" |
13 #include "net/base/net_util.h" | 13 #include "net/base/net_util.h" |
14 #include "ppapi/c/dev/ppb_var_array_buffer_dev.h" | 14 #include "ppapi/c/dev/ppb_var_array_buffer_dev.h" |
15 #include "ppapi/c/pp_completion_callback.h" | 15 #include "ppapi/c/pp_completion_callback.h" |
16 #include "ppapi/c/pp_errors.h" | 16 #include "ppapi/c/pp_errors.h" |
17 #include "ppapi/c/pp_var.h" | 17 #include "ppapi/c/pp_var.h" |
18 #include "ppapi/c/ppb_var.h" | 18 #include "ppapi/c/ppb_var.h" |
19 #include "ppapi/shared_impl/var.h" | 19 #include "ppapi/shared_impl/var.h" |
20 #include "ppapi/shared_impl/var_tracker.h" | 20 #include "ppapi/shared_impl/var_tracker.h" |
21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebData.h" | 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebArrayBuffer.h" |
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" | 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" |
24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" | 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" |
25 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" | 25 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.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 "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" | 27 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" |
28 #include "webkit/plugins/ppapi/host_array_buffer_var.h" | |
28 #include "webkit/plugins/ppapi/host_globals.h" | 29 #include "webkit/plugins/ppapi/host_globals.h" |
29 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 30 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
30 #include "webkit/plugins/ppapi/resource_helper.h" | 31 #include "webkit/plugins/ppapi/resource_helper.h" |
31 | 32 |
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::VarTracker; | 38 using ppapi::VarTracker; |
38 using WebKit::WebData; | 39 using WebKit::WebArrayBuffer; |
39 using WebKit::WebDocument; | 40 using WebKit::WebDocument; |
40 using WebKit::WebString; | 41 using WebKit::WebString; |
41 using WebKit::WebSocket; | 42 using WebKit::WebSocket; |
42 using WebKit::WebSocketClient; | 43 using WebKit::WebSocketClient; |
43 using WebKit::WebURL; | 44 using WebKit::WebURL; |
44 | 45 |
45 const uint32_t kMaxReasonSizeInBytes = 123; | 46 const uint32_t kMaxReasonSizeInBytes = 123; |
46 const size_t kHybiBaseFramingOverhead = 2; | 47 const size_t kHybiBaseFramingOverhead = 2; |
47 const size_t kHybiMaskingKeyLength = 4; | 48 const size_t kHybiMaskingKeyLength = 4; |
48 const size_t kMinimumPayloadSizeWithTwoByteExtendedPayloadLength = 126; | 49 const size_t kMinimumPayloadSizeWithTwoByteExtendedPayloadLength = 126; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
87 close_code_(0), | 88 close_code_(0), |
88 close_was_clean_(PP_FALSE), | 89 close_was_clean_(PP_FALSE), |
89 empty_string_(new StringVar("", 0)), | 90 empty_string_(new StringVar("", 0)), |
90 buffered_amount_(0), | 91 buffered_amount_(0), |
91 buffered_amount_after_close_(0) { | 92 buffered_amount_after_close_(0) { |
92 } | 93 } |
93 | 94 |
94 PPB_WebSocket_Impl::~PPB_WebSocket_Impl() { | 95 PPB_WebSocket_Impl::~PPB_WebSocket_Impl() { |
95 if (websocket_.get()) | 96 if (websocket_.get()) |
96 websocket_->disconnect(); | 97 websocket_->disconnect(); |
97 | |
98 // Clean up received and unread messages | |
99 VarTracker* var_tracker = PpapiGlobals::Get()->GetVarTracker(); | |
100 while (!received_messages_.empty()) { | |
101 PP_Var var = received_messages_.front(); | |
102 received_messages_.pop(); | |
103 var_tracker->ReleaseVar(var); | |
104 } | |
105 } | 98 } |
106 | 99 |
107 // static | 100 // static |
108 PP_Resource PPB_WebSocket_Impl::Create(PP_Instance instance) { | 101 PP_Resource PPB_WebSocket_Impl::Create(PP_Instance instance) { |
109 scoped_refptr<PPB_WebSocket_Impl> ws(new PPB_WebSocket_Impl(instance)); | 102 scoped_refptr<PPB_WebSocket_Impl> ws(new PPB_WebSocket_Impl(instance)); |
110 return ws->GetReference(); | 103 return ws->GetReference(); |
111 } | 104 } |
112 | 105 |
113 PPB_WebSocket_API* PPB_WebSocket_Impl::AsPPB_WebSocket_API() { | 106 PPB_WebSocket_API* PPB_WebSocket_Impl::AsPPB_WebSocket_API() { |
114 return this; | 107 return this; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
196 if (!callback.func) | 189 if (!callback.func) |
197 return PP_ERROR_BLOCKS_MAIN_THREAD; | 190 return PP_ERROR_BLOCKS_MAIN_THREAD; |
198 | 191 |
199 // Create WebKit::WebSocket object and connect. | 192 // Create WebKit::WebSocket object and connect. |
200 WebDocument document = plugin_instance->container()->element().document(); | 193 WebDocument document = plugin_instance->container()->element().document(); |
201 websocket_.reset(WebSocket::create(document, this)); | 194 websocket_.reset(WebSocket::create(document, this)); |
202 DCHECK(websocket_.get()); | 195 DCHECK(websocket_.get()); |
203 if (!websocket_.get()) | 196 if (!websocket_.get()) |
204 return PP_ERROR_NOTSUPPORTED; | 197 return PP_ERROR_NOTSUPPORTED; |
205 | 198 |
199 // Set receiving binary object type. | |
200 websocket_->setBinaryType(static_cast<WebSocket::BinaryType>(binary_type_)); | |
dmichael (off chromium)
2012/01/13 17:36:14
It seems like it would be a good idea to either co
Takashi Toyoshima
2012/01/17 10:14:59
OK, I hold this value as WebSocket::BinaryType, th
| |
201 | |
206 websocket_->connect(web_url, web_protocols); | 202 websocket_->connect(web_url, web_protocols); |
207 state_ = PP_WEBSOCKETREADYSTATE_CONNECTING_DEV; | 203 state_ = PP_WEBSOCKETREADYSTATE_CONNECTING_DEV; |
208 | 204 |
209 // Install callback. | 205 // Install callback. |
210 connect_callback_ = new TrackedCallback(this, callback); | 206 connect_callback_ = new TrackedCallback(this, callback); |
211 | 207 |
212 return PP_OK_COMPLETIONPENDING; | 208 return PP_OK_COMPLETIONPENDING; |
213 } | 209 } |
214 | 210 |
215 int32_t PPB_WebSocket_Impl::Close(uint16_t code, | 211 int32_t PPB_WebSocket_Impl::Close(uint16_t code, |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
350 // Send the message. | 346 // Send the message. |
351 if (message.type == PP_VARTYPE_STRING) { | 347 if (message.type == PP_VARTYPE_STRING) { |
352 // Convert message to WebString. | 348 // Convert message to WebString. |
353 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message); | 349 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message); |
354 if (!message_string) | 350 if (!message_string) |
355 return PP_ERROR_BADARGUMENT; | 351 return PP_ERROR_BADARGUMENT; |
356 WebString web_message = WebString::fromUTF8(message_string->value()); | 352 WebString web_message = WebString::fromUTF8(message_string->value()); |
357 if (!websocket_->sendText(web_message)) | 353 if (!websocket_->sendText(web_message)) |
358 return PP_ERROR_BADARGUMENT; | 354 return PP_ERROR_BADARGUMENT; |
359 } else if (message.type == PP_VARTYPE_ARRAY_BUFFER) { | 355 } else if (message.type == PP_VARTYPE_ARRAY_BUFFER) { |
360 // Convert message to WebData. | 356 // Convert message to WebArrayBuffer. |
361 // TODO(toyoshim): Must add a WebKit interface which handles WebArrayBuffer | 357 scoped_refptr<HostArrayBufferVar> host_message = |
362 // directly. | 358 static_cast<HostArrayBufferVar*>(ArrayBufferVar::FromPPVar(message)); |
363 scoped_refptr<ArrayBufferVar> message_array_buffer = | 359 if (!host_message) |
364 ArrayBufferVar::FromPPVar(message); | |
365 if (!message_array_buffer) | |
366 return PP_ERROR_BADARGUMENT; | 360 return PP_ERROR_BADARGUMENT; |
367 WebData web_message = WebData( | 361 WebArrayBuffer& web_message = host_message->webkit_buffer(); |
368 static_cast<const char*>(message_array_buffer->Map()), | 362 if (!websocket_->sendArrayBuffer(web_message)) |
369 static_cast<size_t>(message_array_buffer->ByteLength())); | |
370 if (!websocket_->sendBinary(web_message)) | |
371 return PP_ERROR_BADARGUMENT; | 363 return PP_ERROR_BADARGUMENT; |
372 } else { | 364 } else { |
373 // TODO(toyoshim): Support Blob. | 365 // TODO(toyoshim): Support Blob. |
374 return PP_ERROR_NOTSUPPORTED; | 366 return PP_ERROR_NOTSUPPORTED; |
375 } | 367 } |
376 | 368 |
377 return PP_OK; | 369 return PP_OK; |
378 } | 370 } |
379 | 371 |
380 uint64_t PPB_WebSocket_Impl::GetBufferedAmount() { | 372 uint64_t PPB_WebSocket_Impl::GetBufferedAmount() { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 } | 409 } |
418 | 410 |
419 PP_Var PPB_WebSocket_Impl::GetURL() { | 411 PP_Var PPB_WebSocket_Impl::GetURL() { |
420 if (!url_) | 412 if (!url_) |
421 return empty_string_->GetPPVar(); | 413 return empty_string_->GetPPVar(); |
422 return url_->GetPPVar(); | 414 return url_->GetPPVar(); |
423 } | 415 } |
424 | 416 |
425 PP_Bool PPB_WebSocket_Impl::SetBinaryType( | 417 PP_Bool PPB_WebSocket_Impl::SetBinaryType( |
426 PP_WebSocketBinaryType_Dev binary_type) { | 418 PP_WebSocketBinaryType_Dev binary_type) { |
427 // TODO(toyoshim): Use WebKit new API to set the receiving binary type. | 419 binary_type_ = binary_type; |
428 return PP_FALSE; | 420 if (websocket_.get()) |
421 websocket_->setBinaryType( | |
422 static_cast<WebSocket::BinaryType>(binary_type_)); | |
dmichael (off chromium)
2012/01/13 17:36:14
Ditto, some better checking would be good here. Re
Takashi Toyoshima
2012/01/17 10:14:59
Done.
| |
423 return PP_TRUE; | |
429 } | 424 } |
430 | 425 |
431 PP_WebSocketBinaryType_Dev PPB_WebSocket_Impl::GetBinaryType() { | 426 PP_WebSocketBinaryType_Dev PPB_WebSocket_Impl::GetBinaryType() { |
432 return binary_type_; | 427 return binary_type_; |
433 } | 428 } |
434 | 429 |
435 void PPB_WebSocket_Impl::didConnect() { | 430 void PPB_WebSocket_Impl::didConnect() { |
436 DCHECK_EQ(PP_WEBSOCKETREADYSTATE_CONNECTING_DEV, state_); | 431 DCHECK_EQ(PP_WEBSOCKETREADYSTATE_CONNECTING_DEV, state_); |
437 state_ = PP_WEBSOCKETREADYSTATE_OPEN_DEV; | 432 state_ = PP_WEBSOCKETREADYSTATE_OPEN_DEV; |
438 TrackedCallback::ClearAndRun(&connect_callback_, PP_OK); | 433 TrackedCallback::ClearAndRun(&connect_callback_, PP_OK); |
439 } | 434 } |
440 | 435 |
441 void PPB_WebSocket_Impl::didReceiveMessage(const WebString& message) { | 436 void PPB_WebSocket_Impl::didReceiveMessage(const WebString& message) { |
442 // Dispose packets after receiving an error or in invalid state. | 437 // Dispose packets after receiving an error or in invalid state. |
443 if (error_was_received_ || !InValidStateToReceive(state_)) | 438 if (error_was_received_ || !InValidStateToReceive(state_)) |
444 return; | 439 return; |
445 | 440 |
446 // Append received data to queue. | 441 // Append received data to queue. |
447 std::string string = message.utf8(); | 442 std::string string = message.utf8(); |
448 PP_Var var = StringVar::StringToPPVar(string); | 443 received_messages_.push(new StringVar(string)); |
dmichael (off chromium)
2012/01/13 17:36:14
So now the vars in your queue have no ID and no re
Takashi Toyoshima
2012/01/17 10:14:59
Oh, sorry. I confused on managing ref counted obje
| |
449 received_messages_.push(var); | |
450 | 444 |
451 if (!wait_for_receive_) | 445 if (!wait_for_receive_) |
452 return; | 446 return; |
453 | 447 |
454 TrackedCallback::ClearAndRun(&receive_callback_, DoReceive()); | 448 TrackedCallback::ClearAndRun(&receive_callback_, DoReceive()); |
455 } | 449 } |
456 | 450 |
457 void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) { | 451 void PPB_WebSocket_Impl::didReceiveArrayBuffer( |
452 const WebArrayBuffer& binaryData) { | |
458 // Dispose packets after receiving an error or in invalid state. | 453 // Dispose packets after receiving an error or in invalid state. |
459 if (error_was_received_ || !InValidStateToReceive(state_)) | 454 if (error_was_received_ || !InValidStateToReceive(state_)) |
460 return; | 455 return; |
461 | 456 |
462 // Append received data to queue. | 457 // Append received data to queue. |
463 PP_Var var = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( | 458 scoped_refptr<ArrayBufferVar> var = new HostArrayBufferVar(binaryData); |
464 binaryData.size()); | |
465 scoped_refptr<ArrayBufferVar> arraybuffer = ArrayBufferVar::FromPPVar(var); | |
466 void* data = arraybuffer->Map(); | |
467 memcpy(data, binaryData.data(), binaryData.size()); | |
468 received_messages_.push(var); | 459 received_messages_.push(var); |
dmichael (off chromium)
2012/01/13 17:36:14
Does this compile, to pass a scoped_refptr when a
Takashi Toyoshima
2012/01/17 10:14:59
Fixed.
| |
469 | 460 |
470 if (!wait_for_receive_) | 461 if (!wait_for_receive_) |
471 return; | 462 return; |
472 | 463 |
473 TrackedCallback::ClearAndRun(&receive_callback_, DoReceive()); | 464 TrackedCallback::ClearAndRun(&receive_callback_, DoReceive()); |
474 } | 465 } |
475 | 466 |
476 void PPB_WebSocket_Impl::didReceiveMessageError() { | 467 void PPB_WebSocket_Impl::didReceiveMessageError() { |
477 // Ignore error notification in invalid state. | 468 // Ignore error notification in invalid state. |
478 if (!InValidStateToReceive(state_)) | 469 if (!InValidStateToReceive(state_)) |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
541 | 532 |
542 // Disconnect. | 533 // Disconnect. |
543 if (websocket_.get()) | 534 if (websocket_.get()) |
544 websocket_->disconnect(); | 535 websocket_->disconnect(); |
545 } | 536 } |
546 | 537 |
547 int32_t PPB_WebSocket_Impl::DoReceive() { | 538 int32_t PPB_WebSocket_Impl::DoReceive() { |
548 if (!receive_callback_var_) | 539 if (!receive_callback_var_) |
549 return PP_OK; | 540 return PP_OK; |
550 | 541 |
551 *receive_callback_var_ = received_messages_.front(); | 542 *receive_callback_var_ = received_messages_.front()->GetPPVar(); |
552 received_messages_.pop(); | 543 received_messages_.pop(); |
553 receive_callback_var_ = NULL; | 544 receive_callback_var_ = NULL; |
554 wait_for_receive_ = false; | 545 wait_for_receive_ = false; |
555 return PP_OK; | 546 return PP_OK; |
556 } | 547 } |
557 | 548 |
558 } // namespace ppapi | 549 } // namespace ppapi |
559 } // namespace webkit | 550 } // namespace webkit |
OLD | NEW |