OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "native_client/src/shared/ppapi_proxy/plugin_ppb_websocket.h" |
| 6 |
| 7 #include "native_client/src/include/nacl_scoped_ptr.h" |
| 8 #include "native_client/src/shared/ppapi_proxy/object_serialize.h" |
| 9 #include "native_client/src/shared/ppapi_proxy/plugin_callback.h" |
| 10 #include "native_client/src/shared/ppapi_proxy/plugin_globals.h" |
| 11 #include "native_client/src/shared/ppapi_proxy/utility.h" |
| 12 #include "native_client/src/shared/srpc/nacl_srpc.h" |
| 13 #include "ppapi/c/pp_completion_callback.h" |
| 14 #include "ppapi/c/pp_errors.h" |
| 15 #include "ppapi/c/pp_var.h" |
| 16 #include "ppapi/c/dev/ppb_websocket_dev.h" |
| 17 #include "srpcgen/ppb_rpc.h" |
| 18 |
| 19 namespace ppapi_proxy { |
| 20 |
| 21 namespace { |
| 22 |
| 23 PP_Resource Create(PP_Instance instance) { |
| 24 DebugPrintf("PPB_WebSocket::Create: instance=%"NACL_PRId32"\n", instance); |
| 25 |
| 26 PP_Resource resource; |
| 27 NaClSrpcError srpc_result = |
| 28 PpbWebSocketRpcClient::PPB_WebSocket_Create( |
| 29 GetMainSrpcChannel(), instance, &resource); |
| 30 DebugPrintf("PPB_WebSocket::Create: %s\n", NaClSrpcErrorString(srpc_result)); |
| 31 |
| 32 if (srpc_result == NACL_SRPC_RESULT_OK) |
| 33 return resource; |
| 34 return kInvalidResourceId; |
| 35 } |
| 36 |
| 37 PP_Bool IsWebSocket(PP_Resource resource) { |
| 38 DebugPrintf( |
| 39 "PPB_WebSocket::IsWebSocket: resource=%"NACL_PRId32"\n", resource); |
| 40 |
| 41 int32_t is_websocket; |
| 42 NaClSrpcError srpc_result = |
| 43 PpbWebSocketRpcClient::PPB_WebSocket_IsWebSocket( |
| 44 GetMainSrpcChannel(), resource, &is_websocket); |
| 45 DebugPrintf("PPB_WebSocket::IsWebSocket: %s\n", |
| 46 NaClSrpcErrorString(srpc_result)); |
| 47 |
| 48 if (srpc_result == NACL_SRPC_RESULT_OK && is_websocket) |
| 49 return PP_TRUE; |
| 50 return PP_FALSE; |
| 51 } |
| 52 |
| 53 int32_t Connect(PP_Resource ws, |
| 54 PP_Var url, |
| 55 const PP_Var protocols[], |
| 56 uint32_t protocol_count, |
| 57 PP_CompletionCallback callback) { |
| 58 DebugPrintf("PPB_WebSocket::Connect: ws=%"NACL_PRId32"\n", ws); |
| 59 |
| 60 nacl_abi_size_t url_size = 0; |
| 61 nacl::scoped_array<char> url_bytes(Serialize(&url, 1, &url_size)); |
| 62 |
| 63 nacl_abi_size_t protocols_size = 0; |
| 64 nacl::scoped_array<char> protocols_bytes( |
| 65 Serialize(protocols, protocol_count, &protocols_size)); |
| 66 |
| 67 int32_t callback_id = CompletionCallbackTable::Get()->AddCallback(callback); |
| 68 if (callback_id == 0) |
| 69 return PP_ERROR_BLOCKS_MAIN_THREAD; |
| 70 |
| 71 int32_t pp_error; |
| 72 NaClSrpcError srpc_result = |
| 73 PpbWebSocketRpcClient::PPB_WebSocket_Connect( |
| 74 GetMainSrpcChannel(), |
| 75 ws, |
| 76 url_size, url_bytes.get(), |
| 77 protocols_size, protocols_bytes.get(), |
| 78 static_cast<int32_t>(protocol_count), |
| 79 callback_id, |
| 80 &pp_error); |
| 81 DebugPrintf("PPB_WebSocket::Connect: %s\n", |
| 82 NaClSrpcErrorString(srpc_result)); |
| 83 |
| 84 if (srpc_result != NACL_SRPC_RESULT_OK) |
| 85 pp_error = PP_ERROR_FAILED; |
| 86 return MayForceCallback(callback, pp_error); |
| 87 } |
| 88 |
| 89 int32_t Close(PP_Resource ws, |
| 90 uint16_t code, |
| 91 PP_Var reason, |
| 92 PP_CompletionCallback callback) { |
| 93 DebugPrintf("PPB_WebSocket::Close: ws=%"NACL_PRId32"\n", ws); |
| 94 |
| 95 nacl_abi_size_t reason_size = 0; |
| 96 nacl::scoped_array<char> reason_bytes(Serialize(&reason, 1, &reason_size)); |
| 97 |
| 98 int32_t callback_id = CompletionCallbackTable::Get()->AddCallback(callback); |
| 99 if (callback_id == 0) |
| 100 return PP_ERROR_BLOCKS_MAIN_THREAD; |
| 101 |
| 102 int32_t pp_error; |
| 103 NaClSrpcError srpc_result = |
| 104 PpbWebSocketRpcClient::PPB_WebSocket_Close( |
| 105 GetMainSrpcChannel(), |
| 106 ws, |
| 107 code, |
| 108 reason_size, reason_bytes.get(), |
| 109 callback_id, |
| 110 &pp_error); |
| 111 DebugPrintf("PPB_WebSocket::Close: %s\n", NaClSrpcErrorString(srpc_result)); |
| 112 |
| 113 if (srpc_result != NACL_SRPC_RESULT_OK) |
| 114 pp_error = PP_ERROR_FAILED; |
| 115 return MayForceCallback(callback, pp_error); |
| 116 } |
| 117 |
| 118 int32_t ReceiveMessage(PP_Resource ws, |
| 119 PP_Var* message, |
| 120 PP_CompletionCallback callback) { |
| 121 DebugPrintf("PPB_WebSocket::ReceiveMessage: ws=%"NACL_PRId32"\n", ws); |
| 122 |
| 123 int32_t callback_id = |
| 124 CompletionCallbackTable::Get()->AddCallback(callback, message); |
| 125 if (callback_id == 0) |
| 126 return PP_ERROR_BLOCKS_MAIN_THREAD; |
| 127 |
| 128 // TODO(toyoshim): ReceiveMessage needs performance optimization to reduce |
| 129 // chances to call RPC. |
| 130 int32_t pp_error; |
| 131 NaClSrpcError srpc_result = |
| 132 PpbWebSocketRpcClient::PPB_WebSocket_ReceiveMessage( |
| 133 GetMainSrpcChannel(), |
| 134 ws, |
| 135 callback_id, |
| 136 &pp_error); |
| 137 DebugPrintf("PPB_WebSocket::ReceiveMessage: %s\n", |
| 138 NaClSrpcErrorString(srpc_result)); |
| 139 |
| 140 if (srpc_result != NACL_SRPC_RESULT_OK) |
| 141 pp_error = PP_ERROR_FAILED; |
| 142 return MayForceCallback(callback, pp_error); |
| 143 } |
| 144 |
| 145 int32_t SendMessage(PP_Resource ws, |
| 146 PP_Var message) { |
| 147 DebugPrintf("PPB_WebSocket::SendMessage: ws=%"NACL_PRId32"\n", ws); |
| 148 |
| 149 nacl_abi_size_t message_size = 0; |
| 150 nacl::scoped_array<char> message_bytes( |
| 151 Serialize(&message, 1, &message_size)); |
| 152 |
| 153 int32_t pp_error; |
| 154 NaClSrpcError srpc_result = |
| 155 PpbWebSocketRpcClient::PPB_WebSocket_SendMessage( |
| 156 GetMainSrpcChannel(), |
| 157 ws, |
| 158 message_size, message_bytes.get(), |
| 159 &pp_error); |
| 160 DebugPrintf("PPB_WebSocket::SendMessage: %s\n", |
| 161 NaClSrpcErrorString(srpc_result)); |
| 162 |
| 163 if (srpc_result != NACL_SRPC_RESULT_OK) |
| 164 return PP_ERROR_FAILED; |
| 165 return pp_error; |
| 166 } |
| 167 |
| 168 uint64_t GetBufferedAmount(PP_Resource ws) { |
| 169 DebugPrintf("PPB_WebSocket::GetBufferedAmount: ws=%"NACL_PRId32"\n", ws); |
| 170 |
| 171 int64_t buffered_amount = 0; |
| 172 NaClSrpcError srpc_result = |
| 173 PpbWebSocketRpcClient::PPB_WebSocket_GetBufferedAmount( |
| 174 GetMainSrpcChannel(), ws, &buffered_amount); |
| 175 DebugPrintf("PPB_WebSocket::GetBufferedAmount: %s\n", |
| 176 NaClSrpcErrorString(srpc_result)); |
| 177 |
| 178 return static_cast<uint64_t>(buffered_amount); |
| 179 } |
| 180 |
| 181 uint16_t GetCloseCode(PP_Resource ws) { |
| 182 DebugPrintf("PPB_WebSocket::GetCloseCode: ws=%"NACL_PRId32"\n", ws); |
| 183 |
| 184 int32_t close_code = 0; |
| 185 NaClSrpcError srpc_result = |
| 186 PpbWebSocketRpcClient::PPB_WebSocket_GetCloseCode( |
| 187 GetMainSrpcChannel(), ws, &close_code); |
| 188 DebugPrintf("PPB_WebSocket::GetCloseCode: %s\n", |
| 189 NaClSrpcErrorString(srpc_result)); |
| 190 |
| 191 return static_cast<uint16_t>(close_code); |
| 192 } |
| 193 |
| 194 PP_Var GetCloseReason(PP_Resource ws) { |
| 195 DebugPrintf("PPB_WebSocket::GetCloseReason: ws=%"NACL_PRId32"\n", ws); |
| 196 |
| 197 nacl_abi_size_t reason_size = kMaxReturnVarSize; |
| 198 nacl::scoped_array<char> reason_bytes(new char[reason_size]); |
| 199 NaClSrpcError srpc_result = |
| 200 PpbWebSocketRpcClient::PPB_WebSocket_GetCloseReason( |
| 201 GetMainSrpcChannel(), ws, &reason_size, reason_bytes.get()); |
| 202 DebugPrintf("PPB_WebSocket::GetCloseReason: %s\n", |
| 203 NaClSrpcErrorString(srpc_result)); |
| 204 |
| 205 if (srpc_result == NACL_SRPC_RESULT_OK) { |
| 206 PP_Var reason = PP_MakeUndefined(); |
| 207 if (DeserializeTo(reason_bytes.get(), reason_size, 1, &reason)) |
| 208 return reason; |
| 209 } |
| 210 |
| 211 return PP_MakeUndefined(); |
| 212 } |
| 213 |
| 214 PP_Bool GetCloseWasClean(PP_Resource ws) { |
| 215 DebugPrintf( |
| 216 "PPB_WebSocket::GetCloseWasClean: ws=%"NACL_PRId32"\n", ws); |
| 217 |
| 218 int32_t was_clean; |
| 219 NaClSrpcError srpc_result = |
| 220 PpbWebSocketRpcClient::PPB_WebSocket_GetCloseWasClean( |
| 221 GetMainSrpcChannel(), ws, &was_clean); |
| 222 DebugPrintf("PPB_WebSocket::GetCloseWasClean: %s\n", |
| 223 NaClSrpcErrorString(srpc_result)); |
| 224 |
| 225 if (srpc_result == NACL_SRPC_RESULT_OK && was_clean) |
| 226 return PP_TRUE; |
| 227 return PP_FALSE; |
| 228 } |
| 229 |
| 230 PP_Var GetExtensions(PP_Resource ws) { |
| 231 DebugPrintf("PPB_WebSocket::GetExtensions: ws=%"NACL_PRId32"\n", ws); |
| 232 |
| 233 nacl_abi_size_t extensions_size = kMaxReturnVarSize; |
| 234 nacl::scoped_array<char> extensions_bytes(new char[extensions_size]); |
| 235 NaClSrpcError srpc_result = |
| 236 PpbWebSocketRpcClient::PPB_WebSocket_GetExtensions( |
| 237 GetMainSrpcChannel(), ws, &extensions_size, extensions_bytes.get()); |
| 238 DebugPrintf("PPB_WebSocket::GetExtensions: %s\n", |
| 239 NaClSrpcErrorString(srpc_result)); |
| 240 |
| 241 if (srpc_result == NACL_SRPC_RESULT_OK) { |
| 242 PP_Var extensions = PP_MakeUndefined(); |
| 243 if (DeserializeTo(extensions_bytes.get(), extensions_size, 1, &extensions)) |
| 244 return extensions; |
| 245 } |
| 246 |
| 247 return PP_MakeUndefined(); |
| 248 } |
| 249 |
| 250 PP_Var GetProtocol(PP_Resource ws) { |
| 251 DebugPrintf("PPB_WebSocket::GetProtocol: ws=%"NACL_PRId32"\n", ws); |
| 252 |
| 253 nacl_abi_size_t protocol_size = kMaxReturnVarSize; |
| 254 nacl::scoped_array<char> protocol_bytes(new char[protocol_size]); |
| 255 NaClSrpcError srpc_result = |
| 256 PpbWebSocketRpcClient::PPB_WebSocket_GetProtocol( |
| 257 GetMainSrpcChannel(), ws, &protocol_size, protocol_bytes.get()); |
| 258 DebugPrintf("PPB_WebSocket::GetProtocol: %s\n", |
| 259 NaClSrpcErrorString(srpc_result)); |
| 260 |
| 261 if (srpc_result == NACL_SRPC_RESULT_OK) { |
| 262 PP_Var protocol = PP_MakeUndefined(); |
| 263 if (DeserializeTo(protocol_bytes.get(), protocol_size, 1, &protocol)) |
| 264 return protocol; |
| 265 } |
| 266 |
| 267 return PP_MakeUndefined(); |
| 268 } |
| 269 |
| 270 PP_WebSocketReadyState_Dev GetReadyState(PP_Resource ws) { |
| 271 DebugPrintf( |
| 272 "PPB_WebSocket::GetReadyState: ws=%"NACL_PRId32"\n", ws); |
| 273 |
| 274 int32_t ready_state; |
| 275 NaClSrpcError srpc_result = |
| 276 PpbWebSocketRpcClient::PPB_WebSocket_GetReadyState( |
| 277 GetMainSrpcChannel(), ws, &ready_state); |
| 278 DebugPrintf("PPB_WebSocket::GetReadyState: %s\n", |
| 279 NaClSrpcErrorString(srpc_result)); |
| 280 |
| 281 if (srpc_result != NACL_SRPC_RESULT_OK) |
| 282 return PP_WEBSOCKETREADYSTATE_INVALID_DEV; |
| 283 return static_cast<PP_WebSocketReadyState_Dev>(ready_state); |
| 284 } |
| 285 |
| 286 PP_Var GetURL(PP_Resource ws) { |
| 287 DebugPrintf("PPB_WebSocket::GetURL: ws=%"NACL_PRId32"\n", ws); |
| 288 |
| 289 nacl_abi_size_t url_size = kMaxReturnVarSize; |
| 290 nacl::scoped_array<char> url_bytes(new char[url_size]); |
| 291 NaClSrpcError srpc_result = |
| 292 PpbWebSocketRpcClient::PPB_WebSocket_GetURL( |
| 293 GetMainSrpcChannel(), ws, &url_size, url_bytes.get()); |
| 294 DebugPrintf("PPB_WebSocket::GetURL: %s\n", |
| 295 NaClSrpcErrorString(srpc_result)); |
| 296 |
| 297 if (srpc_result == NACL_SRPC_RESULT_OK) { |
| 298 PP_Var url = PP_MakeUndefined(); |
| 299 if (DeserializeTo(url_bytes.get(), url_size, 1, &url)) |
| 300 return url; |
| 301 } |
| 302 |
| 303 return PP_MakeUndefined(); |
| 304 } |
| 305 |
| 306 PP_Bool SetBinaryType(PP_Resource ws, |
| 307 PP_WebSocketBinaryType_Dev binary_type) { |
| 308 DebugPrintf("PPB_WebSocket::SetBinaryType: ws=%"NACL_PRId32"\n", ws); |
| 309 |
| 310 int32_t success; |
| 311 NaClSrpcError srpc_result = |
| 312 PpbWebSocketRpcClient::PPB_WebSocket_SetBinaryType( |
| 313 GetMainSrpcChannel(), |
| 314 ws, |
| 315 static_cast<int32_t>(binary_type), |
| 316 &success); |
| 317 DebugPrintf("PPB_WebSocket::SetBinaryType: %s\n", |
| 318 NaClSrpcErrorString(srpc_result)); |
| 319 |
| 320 if (srpc_result == NACL_SRPC_RESULT_OK && success) |
| 321 return PP_TRUE; |
| 322 return PP_FALSE; |
| 323 } |
| 324 |
| 325 PP_WebSocketBinaryType_Dev GetBinaryType(PP_Resource ws) { |
| 326 DebugPrintf("PPB_WebSocket::GetBinaryType: ws=%"NACL_PRId32"\n", ws); |
| 327 |
| 328 int32_t binary_type; |
| 329 NaClSrpcError srpc_result = |
| 330 PpbWebSocketRpcClient::PPB_WebSocket_GetBinaryType( |
| 331 GetMainSrpcChannel(), |
| 332 ws, |
| 333 &binary_type); |
| 334 DebugPrintf("PPB_WebSocket::GetBinaryType: %s\n", |
| 335 NaClSrpcErrorString(srpc_result)); |
| 336 |
| 337 if (srpc_result != NACL_SRPC_RESULT_OK) |
| 338 return PP_WEBSOCKETBINARYTYPE_INVALID; |
| 339 return static_cast<PP_WebSocketBinaryType_Dev>(binary_type); |
| 340 } |
| 341 |
| 342 } // namespace |
| 343 |
| 344 const PPB_WebSocket_Dev* PluginWebSocket::GetInterface() { |
| 345 static const PPB_WebSocket_Dev websocket_interface = { |
| 346 &Create, |
| 347 &IsWebSocket, |
| 348 &Connect, |
| 349 &Close, |
| 350 &ReceiveMessage, |
| 351 &SendMessage, |
| 352 &GetBufferedAmount, |
| 353 &GetCloseCode, |
| 354 &GetCloseReason, |
| 355 &GetCloseWasClean, |
| 356 &GetExtensions, |
| 357 &GetProtocol, |
| 358 &GetReadyState, |
| 359 &GetURL, |
| 360 &SetBinaryType, |
| 361 &GetBinaryType |
| 362 }; |
| 363 return &websocket_interface; |
| 364 } |
| 365 |
| 366 } // namespace ppapi_proxy |
OLD | NEW |