Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: webkit/plugins/ppapi/ppb_websocket_impl.cc

Issue 10081020: PPAPI: Make blocking completion callbacks work. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Updated TestURLLoader to test blocking callbacks. Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698