OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2009 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 "chrome/renderer/socket_stream_dispatcher.h" | |
6 | |
7 #include <vector> | |
8 | |
9 #include "base/id_map.h" | |
10 #include "base/ref_counted.h" | |
11 #include "chrome/common/render_messages.h" | |
12 #include "chrome/common/net/socket_stream.h" | |
13 #include "chrome/renderer/render_thread.h" | |
14 #include "googleurl/src/gurl.h" | |
15 #include "webkit/glue/websocketstreamhandle_bridge.h" | |
16 #include "webkit/glue/websocketstreamhandle_delegate.h" | |
17 | |
18 // IPCWebSocketStreamHandleBridge is owned by each SocketStreamHandle. | |
19 // It communicates with the main browser process via SocketStreamDispatcher. | |
20 class IPCWebSocketStreamHandleBridge | |
21 : public webkit_glue::WebSocketStreamHandleBridge { | |
22 public: | |
23 IPCWebSocketStreamHandleBridge( | |
24 IPC::Message::Sender* sender, | |
25 WebKit::WebSocketStreamHandle* handle, | |
26 webkit_glue::WebSocketStreamHandleDelegate* delegate) | |
27 : socket_id_(chrome_common_net::kNoSocketId), | |
28 sender_(sender), | |
29 handle_(handle), | |
30 delegate_(delegate) {} | |
31 | |
32 // Returns the handle having given id or NULL if there is no such handle. | |
33 static IPCWebSocketStreamHandleBridge* FromSocketId(int id); | |
34 | |
35 // webkit_glue::WebSocketStreamHandleBridge methods. | |
36 virtual void Connect(const GURL& url); | |
37 virtual bool Send(const std::vector<char>& data); | |
38 virtual void Close(); | |
39 | |
40 // Called by SocketStreamDispatcher. | |
41 void OnConnected(int max_amount_send_allowed); | |
42 void OnSentData(int amount_sent); | |
43 void OnReceivedData(const std::vector<char>& data); | |
44 void OnClosed(); | |
45 | |
46 private: | |
47 virtual ~IPCWebSocketStreamHandleBridge(); | |
48 | |
49 void DoConnect(const GURL& url); | |
50 int socket_id_; | |
51 | |
52 IPC::Message::Sender* sender_; | |
53 WebKit::WebSocketStreamHandle* handle_; | |
54 webkit_glue::WebSocketStreamHandleDelegate* delegate_; | |
55 | |
56 static IDMap<IPCWebSocketStreamHandleBridge> all_bridges; | |
57 }; | |
58 | |
59 IDMap<IPCWebSocketStreamHandleBridge> | |
60 IPCWebSocketStreamHandleBridge::all_bridges; | |
61 | |
62 /* static */ | |
63 IPCWebSocketStreamHandleBridge* IPCWebSocketStreamHandleBridge::FromSocketId( | |
64 int id) { | |
65 return all_bridges.Lookup(id); | |
66 } | |
67 | |
68 IPCWebSocketStreamHandleBridge::~IPCWebSocketStreamHandleBridge() { | |
69 DLOG(INFO) << "IPCWebSocketStreamHandleBridge destructor socket_id=" | |
70 << socket_id_; | |
71 if (socket_id_ != chrome_common_net::kNoSocketId) { | |
72 sender_->Send(new ViewHostMsg_Close(socket_id_)); | |
73 socket_id_ = chrome_common_net::kNoSocketId; | |
74 } | |
75 } | |
76 | |
77 void IPCWebSocketStreamHandleBridge::Connect(const GURL& url) { | |
78 DCHECK(sender_); | |
79 DLOG(INFO) << "Connect url=" << url; | |
80 MessageLoop::current()->PostTask( | |
81 FROM_HERE, | |
82 NewRunnableMethod(this, &IPCWebSocketStreamHandleBridge::DoConnect, | |
83 url)); | |
84 } | |
85 | |
86 bool IPCWebSocketStreamHandleBridge::Send( | |
87 const std::vector<char>& data) { | |
88 DLOG(INFO) << "Send data.size=" << data.size(); | |
89 if (sender_->Send(new ViewHostMsg_SocketStream_SendData(socket_id_, data))) { | |
90 if (delegate_) | |
91 delegate_->WillSendData(handle_, &data[0], data.size()); | |
92 return true; | |
93 } | |
94 return false; | |
95 } | |
96 | |
97 void IPCWebSocketStreamHandleBridge::Close() { | |
98 DLOG(INFO) << "Close socket_id" << socket_id_; | |
99 sender_->Send(new ViewHostMsg_SocketStream_Close(socket_id_)); | |
100 } | |
101 | |
102 void IPCWebSocketStreamHandleBridge::OnConnected(int max_pending_send_allowed) { | |
103 DLOG(INFO) << "IPCWebSocketStreamHandleBridge::OnConnected socket_id=" | |
104 << socket_id_; | |
105 if (delegate_) | |
106 delegate_->DidOpenStream(handle_, max_pending_send_allowed); | |
107 } | |
108 | |
109 void IPCWebSocketStreamHandleBridge::OnSentData(int amount_sent) { | |
110 if (delegate_) | |
111 delegate_->DidSendData(handle_, amount_sent); | |
112 } | |
113 | |
114 void IPCWebSocketStreamHandleBridge::OnReceivedData( | |
115 const std::vector<char>& data) { | |
116 if (delegate_) | |
117 delegate_->DidReceiveData(handle_, &data[0], data.size()); | |
118 } | |
119 | |
120 void IPCWebSocketStreamHandleBridge::OnClosed() { | |
121 DLOG(INFO) << "IPCWebSocketStreamHandleBridge::OnClosed"; | |
122 if (socket_id_ != chrome_common_net::kNoSocketId) { | |
123 all_bridges.Remove(socket_id_); | |
124 socket_id_ = chrome_common_net::kNoSocketId; | |
125 } | |
126 if (delegate_) { | |
127 delegate_->DidClose(handle_); | |
128 } | |
129 delegate_ = NULL; | |
130 Release(); | |
131 } | |
132 | |
133 void IPCWebSocketStreamHandleBridge::DoConnect(const GURL& url) { | |
134 DCHECK(sender_); | |
135 DCHECK_EQ(socket_id_, chrome_common_net::kNoSocketId); | |
136 if (delegate_) | |
137 delegate_->WillOpenStream(handle_, url); | |
138 | |
139 socket_id_ = all_bridges.Add(this); | |
140 DCHECK_NE(socket_id_, chrome_common_net::kNoSocketId); | |
141 if (sender_->Send(new ViewHostMsg_SocketStream_Connect(url, socket_id_))) { | |
142 DLOG(INFO) << "Connect socket_id=" << socket_id_; | |
143 AddRef(); // Released in OnClosed(). | |
144 // TODO(ukai): timeout to OnConnected. | |
145 } else { | |
146 LOG(ERROR) << "IPC SocketStream_Connect failed."; | |
147 OnClosed(); | |
Denis Lagno
2011/01/27 12:21:13
is not it an error? You call OnClosed() which per
ukai
2011/01/28 05:31:28
Ah. good catch!
I'll fix it.
| |
148 } | |
149 } | |
150 | |
151 SocketStreamDispatcher::SocketStreamDispatcher() { | |
152 } | |
153 | |
154 /* static */ | |
155 webkit_glue::WebSocketStreamHandleBridge* | |
156 SocketStreamDispatcher::CreateBridge( | |
157 WebKit::WebSocketStreamHandle* handle, | |
158 webkit_glue::WebSocketStreamHandleDelegate* delegate) { | |
159 return new IPCWebSocketStreamHandleBridge( | |
160 ChildThread::current(), handle, delegate); | |
161 } | |
162 | |
163 bool SocketStreamDispatcher::OnMessageReceived(const IPC::Message& msg) { | |
164 DLOG(INFO) << "SocketStreamDispatcher::OnMessageReceived"; | |
165 bool handled = true; | |
166 IPC_BEGIN_MESSAGE_MAP(SocketStreamDispatcher, msg) | |
167 IPC_MESSAGE_HANDLER(ViewMsg_SocketStream_Connected, OnConnected) | |
168 IPC_MESSAGE_HANDLER(ViewMsg_SocketStream_SentData, OnSentData) | |
169 IPC_MESSAGE_HANDLER(ViewMsg_SocketStream_ReceivedData, OnReceivedData) | |
170 IPC_MESSAGE_HANDLER(ViewMsg_SocketStream_Closed, OnClosed) | |
171 IPC_MESSAGE_UNHANDLED(handled = false) | |
172 IPC_END_MESSAGE_MAP() | |
173 return handled; | |
174 } | |
175 | |
176 void SocketStreamDispatcher::OnConnected(int socket_id, | |
177 int max_pending_send_allowed) { | |
178 DLOG(INFO) << "SocketStreamDispatcher::OnConnected socket_id=" << socket_id | |
179 << " max_pending_send_allowed=" << max_pending_send_allowed; | |
180 IPCWebSocketStreamHandleBridge* bridge = | |
181 IPCWebSocketStreamHandleBridge::FromSocketId(socket_id); | |
182 if (bridge) | |
183 bridge->OnConnected(max_pending_send_allowed); | |
184 else | |
185 DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id; | |
186 } | |
187 | |
188 void SocketStreamDispatcher::OnSentData(int socket_id, int amount_sent) { | |
189 IPCWebSocketStreamHandleBridge* bridge = | |
190 IPCWebSocketStreamHandleBridge::FromSocketId(socket_id); | |
191 if (bridge) | |
192 bridge->OnSentData(amount_sent); | |
193 else | |
194 DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id; | |
195 } | |
196 | |
197 void SocketStreamDispatcher::OnReceivedData( | |
198 int socket_id, const std::vector<char>& data) { | |
199 IPCWebSocketStreamHandleBridge* bridge = | |
200 IPCWebSocketStreamHandleBridge::FromSocketId(socket_id); | |
201 if (bridge) | |
202 bridge->OnReceivedData(data); | |
203 else | |
204 DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id; | |
205 } | |
206 | |
207 void SocketStreamDispatcher::OnClosed(int socket_id) { | |
208 IPCWebSocketStreamHandleBridge* bridge = | |
209 IPCWebSocketStreamHandleBridge::FromSocketId(socket_id); | |
210 if (bridge) | |
211 bridge->OnClosed(); | |
212 else | |
213 DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id; | |
214 } | |
OLD | NEW |