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

Side by Side Diff: ppapi/proxy/ppb_flash_tcp_socket_proxy.cc

Issue 8506016: Remove 'Flash' from TCP/UDP Pepper interfaces. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: resolved last comments Created 9 years, 1 month 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
« no previous file with comments | « ppapi/proxy/ppb_flash_tcp_socket_proxy.h ('k') | ppapi/proxy/ppb_flash_udp_socket_proxy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ppapi/proxy/ppb_flash_tcp_socket_proxy.h"
6
7 #include <algorithm>
8 #include <cstring>
9 #include <map>
10
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop.h"
14 #include "base/task.h"
15 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/proxy/plugin_dispatcher.h"
17 #include "ppapi/proxy/plugin_resource_tracker.h"
18 #include "ppapi/proxy/ppapi_messages.h"
19 #include "ppapi/shared_impl/resource.h"
20 #include "ppapi/thunk/ppb_flash_tcp_socket_api.h"
21 #include "ppapi/thunk/thunk.h"
22
23 using ppapi::thunk::PPB_Flash_TCPSocket_API;
24
25 namespace ppapi {
26 namespace proxy {
27
28 const int32_t kFlashTCPSocketMaxReadSize = 1024 * 1024;
29 const int32_t kFlashTCPSocketMaxWriteSize = 1024 * 1024;
30
31 class FlashTCPSocket;
32
33 namespace {
34
35 typedef std::map<uint32, FlashTCPSocket*> IDToSocketMap;
36 IDToSocketMap* g_id_to_socket = NULL;
37
38 class AbortCallbackTask : public Task {
39 public:
40 explicit AbortCallbackTask(PP_CompletionCallback callback)
41 : callback_(callback) {}
42 virtual ~AbortCallbackTask() {}
43 virtual void Run() {
44 if (callback_.func)
45 PP_RunCompletionCallback(&callback_, PP_ERROR_ABORTED);
46 }
47
48 private:
49 PP_CompletionCallback callback_;
50 };
51
52 } // namespace
53
54 class FlashTCPSocket : public PPB_Flash_TCPSocket_API,
55 public Resource {
56 public:
57 FlashTCPSocket(const HostResource& resource, uint32 socket_id);
58 virtual ~FlashTCPSocket();
59
60 // Resource overrides.
61 virtual PPB_Flash_TCPSocket_API* AsPPB_Flash_TCPSocket_API() OVERRIDE;
62
63 // PPB_Flash_TCPSocket_API implementation.
64 virtual int32_t Connect(const char* host,
65 uint16_t port,
66 PP_CompletionCallback callback) OVERRIDE;
67 virtual int32_t ConnectWithNetAddress(
68 const PP_NetAddress_Private* addr,
69 PP_CompletionCallback callback) OVERRIDE;
70 virtual PP_Bool GetLocalAddress(PP_NetAddress_Private* local_addr) OVERRIDE;
71 virtual PP_Bool GetRemoteAddress(PP_NetAddress_Private* remote_addr) OVERRIDE;
72 virtual int32_t SSLHandshake(const char* server_name,
73 uint16_t server_port,
74 PP_CompletionCallback callback) OVERRIDE;
75 virtual int32_t Read(char* buffer,
76 int32_t bytes_to_read,
77 PP_CompletionCallback callback) OVERRIDE;
78 virtual int32_t Write(const char* buffer,
79 int32_t bytes_to_write,
80 PP_CompletionCallback callback) OVERRIDE;
81 virtual void Disconnect() OVERRIDE;
82
83 // Notifications from the proxy.
84 void OnConnectCompleted(bool succeeded,
85 const PP_NetAddress_Private& local_addr,
86 const PP_NetAddress_Private& remote_addr);
87 void OnSSLHandshakeCompleted(bool succeeded);
88 void OnReadCompleted(bool succeeded, const std::string& data);
89 void OnWriteCompleted(bool succeeded, int32_t bytes_written);
90
91 private:
92 enum ConnectionState {
93 // Before a connection is successfully established (including a connect
94 // request is pending or a previous connect request failed).
95 BEFORE_CONNECT,
96 // A connection has been successfully established (including a request of
97 // initiating SSL is pending).
98 CONNECTED,
99 // An SSL connection has been successfully established.
100 SSL_CONNECTED,
101 // The connection has been ended.
102 DISCONNECTED
103 };
104
105 bool IsConnected() const;
106
107 PluginDispatcher* GetDispatcher() const {
108 return PluginDispatcher::GetForResource(this);
109 }
110
111 // Backend for both Connect() and ConnectWithNetAddress(). To keep things
112 // generic, the message is passed in (on error, it's deleted).
113 int32_t ConnectWithMessage(IPC::Message* msg,
114 PP_CompletionCallback callback);
115
116 void PostAbortAndClearIfNecessary(PP_CompletionCallback* callback);
117
118 uint32 socket_id_;
119 ConnectionState connection_state_;
120
121 PP_CompletionCallback connect_callback_;
122 PP_CompletionCallback ssl_handshake_callback_;
123 PP_CompletionCallback read_callback_;
124 PP_CompletionCallback write_callback_;
125
126 char* read_buffer_;
127 int32_t bytes_to_read_;
128
129 PP_NetAddress_Private local_addr_;
130 PP_NetAddress_Private remote_addr_;
131
132 DISALLOW_COPY_AND_ASSIGN(FlashTCPSocket);
133 };
134
135 FlashTCPSocket::FlashTCPSocket(const HostResource& resource, uint32 socket_id)
136 : Resource(resource),
137 socket_id_(socket_id),
138 connection_state_(BEFORE_CONNECT),
139 connect_callback_(PP_BlockUntilComplete()),
140 ssl_handshake_callback_(PP_BlockUntilComplete()),
141 read_callback_(PP_BlockUntilComplete()),
142 write_callback_(PP_BlockUntilComplete()),
143 read_buffer_(NULL),
144 bytes_to_read_(-1) {
145 DCHECK(socket_id != 0);
146
147 local_addr_.size = 0;
148 memset(local_addr_.data, 0, sizeof(local_addr_.data));
149 remote_addr_.size = 0;
150 memset(remote_addr_.data, 0, sizeof(remote_addr_.data));
151
152 if (!g_id_to_socket)
153 g_id_to_socket = new IDToSocketMap();
154 DCHECK(g_id_to_socket->find(socket_id) == g_id_to_socket->end());
155 (*g_id_to_socket)[socket_id] = this;
156 }
157
158 FlashTCPSocket::~FlashTCPSocket() {
159 Disconnect();
160 }
161
162 PPB_Flash_TCPSocket_API* FlashTCPSocket::AsPPB_Flash_TCPSocket_API() {
163 return this;
164 }
165
166 int32_t FlashTCPSocket::Connect(const char* host,
167 uint16_t port,
168 PP_CompletionCallback callback) {
169 if (!host)
170 return PP_ERROR_BADARGUMENT;
171
172 return ConnectWithMessage(
173 new PpapiHostMsg_PPBFlashTCPSocket_Connect(socket_id_, host, port),
174 callback);
175 }
176
177 int32_t FlashTCPSocket::ConnectWithNetAddress(
178 const PP_NetAddress_Private* addr,
179 PP_CompletionCallback callback) {
180 if (!addr)
181 return PP_ERROR_BADARGUMENT;
182
183 return ConnectWithMessage(
184 new PpapiHostMsg_PPBFlashTCPSocket_ConnectWithNetAddress(
185 socket_id_, *addr),
186 callback);
187 }
188
189 PP_Bool FlashTCPSocket::GetLocalAddress(PP_NetAddress_Private* local_addr) {
190 if (!IsConnected() || !local_addr)
191 return PP_FALSE;
192
193 *local_addr = local_addr_;
194 return PP_TRUE;
195 }
196
197 PP_Bool FlashTCPSocket::GetRemoteAddress(PP_NetAddress_Private* remote_addr) {
198 if (!IsConnected() || !remote_addr)
199 return PP_FALSE;
200
201 *remote_addr = remote_addr_;
202 return PP_TRUE;
203 }
204
205 int32_t FlashTCPSocket::SSLHandshake(const char* server_name,
206 uint16_t server_port,
207 PP_CompletionCallback callback) {
208 if (!server_name)
209 return PP_ERROR_BADARGUMENT;
210 if (!callback.func)
211 return PP_ERROR_BLOCKS_MAIN_THREAD;
212
213 if (connection_state_ != CONNECTED)
214 return PP_ERROR_FAILED;
215 if (ssl_handshake_callback_.func || read_callback_.func ||
216 write_callback_.func)
217 return PP_ERROR_INPROGRESS;
218
219 ssl_handshake_callback_ = callback;
220
221 // Send the request, the browser will call us back via SSLHandshakeACK.
222 GetDispatcher()->SendToBrowser(
223 new PpapiHostMsg_PPBFlashTCPSocket_SSLHandshake(
224 socket_id_, std::string(server_name), server_port));
225 return PP_OK_COMPLETIONPENDING;
226 }
227
228 int32_t FlashTCPSocket::Read(char* buffer,
229 int32_t bytes_to_read,
230 PP_CompletionCallback callback) {
231 if (!buffer || bytes_to_read <= 0)
232 return PP_ERROR_BADARGUMENT;
233 if (!callback.func)
234 return PP_ERROR_BLOCKS_MAIN_THREAD;
235
236 if (!IsConnected())
237 return PP_ERROR_FAILED;
238 if (read_callback_.func || ssl_handshake_callback_.func)
239 return PP_ERROR_INPROGRESS;
240
241 read_buffer_ = buffer;
242 bytes_to_read_ = std::min(bytes_to_read, kFlashTCPSocketMaxReadSize);
243 read_callback_ = callback;
244
245 // Send the request, the browser will call us back via ReadACK.
246 GetDispatcher()->SendToBrowser(
247 new PpapiHostMsg_PPBFlashTCPSocket_Read(socket_id_, bytes_to_read_));
248 return PP_OK_COMPLETIONPENDING;
249 }
250
251 int32_t FlashTCPSocket::Write(const char* buffer,
252 int32_t bytes_to_write,
253 PP_CompletionCallback callback) {
254 if (!buffer || bytes_to_write <= 0)
255 return PP_ERROR_BADARGUMENT;
256 if (!callback.func)
257 return PP_ERROR_BLOCKS_MAIN_THREAD;
258
259 if (!IsConnected())
260 return PP_ERROR_FAILED;
261 if (write_callback_.func || ssl_handshake_callback_.func)
262 return PP_ERROR_INPROGRESS;
263
264 if (bytes_to_write > kFlashTCPSocketMaxWriteSize)
265 bytes_to_write = kFlashTCPSocketMaxWriteSize;
266
267 write_callback_ = callback;
268
269 // Send the request, the browser will call us back via WriteACK.
270 GetDispatcher()->SendToBrowser(
271 new PpapiHostMsg_PPBFlashTCPSocket_Write(
272 socket_id_, std::string(buffer, bytes_to_write)));
273 return PP_OK_COMPLETIONPENDING;
274 }
275
276 void FlashTCPSocket::Disconnect() {
277 if (connection_state_ == DISCONNECTED)
278 return;
279
280 connection_state_ = DISCONNECTED;
281 // After removed from the mapping, this object won't receive any notifications
282 // from the proxy.
283 DCHECK(g_id_to_socket->find(socket_id_) != g_id_to_socket->end());
284 g_id_to_socket->erase(socket_id_);
285
286 GetDispatcher()->SendToBrowser(
287 new PpapiHostMsg_PPBFlashTCPSocket_Disconnect(socket_id_));
288 socket_id_ = 0;
289
290 PostAbortAndClearIfNecessary(&connect_callback_);
291 PostAbortAndClearIfNecessary(&ssl_handshake_callback_);
292 PostAbortAndClearIfNecessary(&read_callback_);
293 PostAbortAndClearIfNecessary(&write_callback_);
294 read_buffer_ = NULL;
295 bytes_to_read_ = -1;
296 }
297
298 void FlashTCPSocket::OnConnectCompleted(
299 bool succeeded,
300 const PP_NetAddress_Private& local_addr,
301 const PP_NetAddress_Private& remote_addr) {
302 if (connection_state_ != BEFORE_CONNECT || !connect_callback_.func) {
303 NOTREACHED();
304 return;
305 }
306
307 if (succeeded) {
308 local_addr_ = local_addr;
309 remote_addr_ = remote_addr;
310 connection_state_ = CONNECTED;
311 }
312 PP_RunAndClearCompletionCallback(&connect_callback_,
313 succeeded ? PP_OK : PP_ERROR_FAILED);
314 }
315
316 void FlashTCPSocket::OnSSLHandshakeCompleted(bool succeeded) {
317 if (connection_state_ != CONNECTED || !ssl_handshake_callback_.func) {
318 NOTREACHED();
319 return;
320 }
321
322 if (succeeded) {
323 connection_state_ = SSL_CONNECTED;
324 PP_RunAndClearCompletionCallback(&ssl_handshake_callback_, PP_OK);
325 } else {
326 PP_RunAndClearCompletionCallback(&ssl_handshake_callback_, PP_ERROR_FAILED);
327 Disconnect();
328 }
329 }
330
331 void FlashTCPSocket::OnReadCompleted(bool succeeded, const std::string& data) {
332 if (!read_callback_.func || !read_buffer_) {
333 NOTREACHED();
334 return;
335 }
336
337 if (succeeded) {
338 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
339 if (!data.empty())
340 memcpy(read_buffer_, data.c_str(), data.size());
341 }
342 read_buffer_ = NULL;
343 bytes_to_read_ = -1;
344
345 PP_RunAndClearCompletionCallback(
346 &read_callback_,
347 succeeded ? static_cast<int32_t>(data.size()) :
348 static_cast<int32_t>(PP_ERROR_FAILED));
349 }
350
351 void FlashTCPSocket::OnWriteCompleted(bool succeeded, int32_t bytes_written) {
352 if (!write_callback_.func || (succeeded && bytes_written < 0)) {
353 NOTREACHED();
354 return;
355 }
356
357 PP_RunAndClearCompletionCallback(
358 &write_callback_,
359 succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED));
360 }
361
362 bool FlashTCPSocket::IsConnected() const {
363 return connection_state_ == CONNECTED || connection_state_ == SSL_CONNECTED;
364 }
365
366 int32_t FlashTCPSocket::ConnectWithMessage(IPC::Message* msg,
367 PP_CompletionCallback callback) {
368 scoped_ptr<IPC::Message> msg_deletor(msg);
369 if (!callback.func)
370 return PP_ERROR_BLOCKS_MAIN_THREAD;
371 if (connection_state_ != BEFORE_CONNECT)
372 return PP_ERROR_FAILED;
373 if (connect_callback_.func)
374 return PP_ERROR_INPROGRESS; // Can only have one pending request.
375
376 connect_callback_ = callback;
377 // Send the request, the browser will call us back via ConnectACK.
378 GetDispatcher()->SendToBrowser(msg_deletor.release());
379 return PP_OK_COMPLETIONPENDING;
380 }
381
382 void FlashTCPSocket::PostAbortAndClearIfNecessary(
383 PP_CompletionCallback* callback) {
384 DCHECK(callback);
385
386 if (callback->func) {
387 MessageLoop::current()->PostTask(FROM_HERE,
388 new AbortCallbackTask(*callback));
389 *callback = PP_BlockUntilComplete();
390 }
391 }
392
393 PPB_Flash_TCPSocket_Proxy::PPB_Flash_TCPSocket_Proxy(Dispatcher* dispatcher)
394 : InterfaceProxy(dispatcher) {
395 }
396
397 PPB_Flash_TCPSocket_Proxy::~PPB_Flash_TCPSocket_Proxy() {
398 }
399
400 // static
401 PP_Resource PPB_Flash_TCPSocket_Proxy::CreateProxyResource(
402 PP_Instance instance) {
403 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
404 if (!dispatcher)
405 return 0;
406
407 uint32 socket_id = 0;
408 dispatcher->SendToBrowser(new PpapiHostMsg_PPBFlashTCPSocket_Create(
409 API_ID_PPB_FLASH_TCPSOCKET, dispatcher->plugin_dispatcher_id(),
410 &socket_id));
411 if (socket_id == 0)
412 return 0;
413 return (new FlashTCPSocket(HostResource::MakeInstanceOnly(instance),
414 socket_id))->GetReference();
415 }
416
417 bool PPB_Flash_TCPSocket_Proxy::OnMessageReceived(const IPC::Message& msg) {
418 bool handled = true;
419 IPC_BEGIN_MESSAGE_MAP(PPB_Flash_TCPSocket_Proxy, msg)
420 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashTCPSocket_ConnectACK, OnMsgConnectACK)
421 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashTCPSocket_SSLHandshakeACK,
422 OnMsgSSLHandshakeACK)
423 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashTCPSocket_ReadACK, OnMsgReadACK)
424 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashTCPSocket_WriteACK, OnMsgWriteACK)
425 IPC_MESSAGE_UNHANDLED(handled = false)
426 IPC_END_MESSAGE_MAP()
427 return handled;
428 }
429
430 void PPB_Flash_TCPSocket_Proxy::OnMsgConnectACK(
431 uint32 /* plugin_dispatcher_id */,
432 uint32 socket_id,
433 bool succeeded,
434 const PP_NetAddress_Private& local_addr,
435 const PP_NetAddress_Private& remote_addr) {
436 if (!g_id_to_socket) {
437 NOTREACHED();
438 return;
439 }
440 IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
441 if (iter == g_id_to_socket->end())
442 return;
443 iter->second->OnConnectCompleted(succeeded, local_addr, remote_addr);
444 }
445
446 void PPB_Flash_TCPSocket_Proxy::OnMsgSSLHandshakeACK(
447 uint32 /* plugin_dispatcher_id */,
448 uint32 socket_id,
449 bool succeeded) {
450 if (!g_id_to_socket) {
451 NOTREACHED();
452 return;
453 }
454 IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
455 if (iter == g_id_to_socket->end())
456 return;
457 iter->second->OnSSLHandshakeCompleted(succeeded);
458 }
459
460 void PPB_Flash_TCPSocket_Proxy::OnMsgReadACK(uint32 /* plugin_dispatcher_id */,
461 uint32 socket_id,
462 bool succeeded,
463 const std::string& data) {
464 if (!g_id_to_socket) {
465 NOTREACHED();
466 return;
467 }
468 IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
469 if (iter == g_id_to_socket->end())
470 return;
471 iter->second->OnReadCompleted(succeeded, data);
472 }
473
474 void PPB_Flash_TCPSocket_Proxy::OnMsgWriteACK(uint32 /* plugin_dispatcher_id */,
475 uint32 socket_id,
476 bool succeeded,
477 int32_t bytes_written) {
478 if (!g_id_to_socket) {
479 NOTREACHED();
480 return;
481 }
482 IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
483 if (iter == g_id_to_socket->end())
484 return;
485 iter->second->OnWriteCompleted(succeeded, bytes_written);
486 }
487
488 } // namespace proxy
489 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/proxy/ppb_flash_tcp_socket_proxy.h ('k') | ppapi/proxy/ppb_flash_udp_socket_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698