[content shell] implement testRunner.overridePreference
[chromium-blink-merge.git] / content / common / socket_stream_dispatcher.cc
blobd4bf448a4a28f00840a7ac7277e1eccb71648da6
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.
5 #include "content/common/socket_stream_dispatcher.h"
7 #include <vector>
9 #include "base/bind.h"
10 #include "base/id_map.h"
11 #include "base/lazy_instance.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/message_loop.h"
14 #include "content/common/child_thread.h"
15 #include "content/common/socket_stream.h"
16 #include "content/common/socket_stream_handle_data.h"
17 #include "content/common/socket_stream_messages.h"
18 #include "googleurl/src/gurl.h"
19 #include "webkit/glue/websocketstreamhandle_bridge.h"
20 #include "webkit/glue/websocketstreamhandle_delegate.h"
22 namespace content {
24 // IPCWebSocketStreamHandleBridge is owned by each SocketStreamHandle.
25 // It communicates with the main browser process via SocketStreamDispatcher.
26 class IPCWebSocketStreamHandleBridge
27 : public webkit_glue::WebSocketStreamHandleBridge {
28 public:
29 IPCWebSocketStreamHandleBridge(
30 ChildThread* child_thread,
31 WebKit::WebSocketStreamHandle* handle,
32 webkit_glue::WebSocketStreamHandleDelegate* delegate)
33 : socket_id_(content::kNoSocketId),
34 child_thread_(child_thread),
35 handle_(handle),
36 delegate_(delegate) {}
38 // Returns the handle having given id or NULL if there is no such handle.
39 static IPCWebSocketStreamHandleBridge* FromSocketId(int id);
41 // webkit_glue::WebSocketStreamHandleBridge methods.
42 virtual void Connect(const GURL& url);
43 virtual bool Send(const std::vector<char>& data);
44 virtual void Close();
46 // Called by SocketStreamDispatcher.
47 void OnConnected(int max_amount_send_allowed);
48 void OnSentData(int amount_sent);
49 void OnReceivedData(const std::vector<char>& data);
50 void OnClosed();
52 private:
53 virtual ~IPCWebSocketStreamHandleBridge();
55 void DoConnect(const GURL& url);
56 void DoClose();
57 int socket_id_;
59 ChildThread* child_thread_;
60 WebKit::WebSocketStreamHandle* handle_;
61 webkit_glue::WebSocketStreamHandleDelegate* delegate_;
63 static base::LazyInstance<IDMap<IPCWebSocketStreamHandleBridge> >::Leaky
64 all_bridges;
67 // static
68 base::LazyInstance<IDMap<IPCWebSocketStreamHandleBridge> >::Leaky
69 IPCWebSocketStreamHandleBridge::all_bridges = LAZY_INSTANCE_INITIALIZER;
71 /* static */
72 IPCWebSocketStreamHandleBridge* IPCWebSocketStreamHandleBridge::FromSocketId(
73 int id) {
74 return all_bridges.Get().Lookup(id);
77 IPCWebSocketStreamHandleBridge::~IPCWebSocketStreamHandleBridge() {
78 DVLOG(1) << "IPCWebSocketStreamHandleBridge destructor socket_id="
79 << socket_id_;
80 if (socket_id_ != content::kNoSocketId) {
81 child_thread_->Send(new SocketStreamHostMsg_Close(socket_id_));
82 socket_id_ = content::kNoSocketId;
86 void IPCWebSocketStreamHandleBridge::Connect(const GURL& url) {
87 DCHECK(child_thread_);
88 DVLOG(1) << "Connect url=" << url;
89 child_thread_->message_loop()->PostTask(
90 FROM_HERE,
91 base::Bind(&IPCWebSocketStreamHandleBridge::DoConnect, this, url));
94 bool IPCWebSocketStreamHandleBridge::Send(
95 const std::vector<char>& data) {
96 DVLOG(1) << "Send data.size=" << data.size();
97 if (child_thread_->Send(
98 new SocketStreamHostMsg_SendData(socket_id_, data))) {
99 if (delegate_)
100 delegate_->WillSendData(handle_, &data[0], data.size());
101 return true;
103 return false;
106 void IPCWebSocketStreamHandleBridge::Close() {
107 DVLOG(1) << "Close socket_id" << socket_id_;
108 AddRef(); // Released in DoClose().
109 child_thread_->message_loop()->PostTask(
110 FROM_HERE,
111 base::Bind(&IPCWebSocketStreamHandleBridge::DoClose, this));
114 void IPCWebSocketStreamHandleBridge::OnConnected(int max_pending_send_allowed) {
115 DVLOG(1) << "IPCWebSocketStreamHandleBridge::OnConnected socket_id="
116 << socket_id_;
117 if (delegate_)
118 delegate_->DidOpenStream(handle_, max_pending_send_allowed);
121 void IPCWebSocketStreamHandleBridge::OnSentData(int amount_sent) {
122 if (delegate_)
123 delegate_->DidSendData(handle_, amount_sent);
126 void IPCWebSocketStreamHandleBridge::OnReceivedData(
127 const std::vector<char>& data) {
128 if (delegate_)
129 delegate_->DidReceiveData(handle_, &data[0], data.size());
132 void IPCWebSocketStreamHandleBridge::OnClosed() {
133 DVLOG(1) << "IPCWebSocketStreamHandleBridge::OnClosed";
134 if (socket_id_ != content::kNoSocketId) {
135 all_bridges.Get().Remove(socket_id_);
136 socket_id_ = content::kNoSocketId;
138 if (delegate_)
139 delegate_->DidClose(handle_);
140 delegate_ = NULL;
141 Release();
144 void IPCWebSocketStreamHandleBridge::DoConnect(const GURL& url) {
145 DCHECK(child_thread_);
146 DCHECK_EQ(socket_id_, content::kNoSocketId);
147 if (delegate_)
148 delegate_->WillOpenStream(handle_, url);
150 socket_id_ = all_bridges.Get().Add(this);
151 DCHECK_NE(socket_id_, content::kNoSocketId);
152 int render_view_id = MSG_ROUTING_NONE;
153 const SocketStreamHandleData* data =
154 SocketStreamHandleData::ForHandle(handle_);
155 if (data)
156 render_view_id = data->render_view_id();
157 AddRef(); // Released in OnClosed().
158 if (child_thread_->Send(
159 new SocketStreamHostMsg_Connect(render_view_id, url, socket_id_))) {
160 DVLOG(1) << "Connect socket_id=" << socket_id_;
161 // TODO(ukai): timeout to OnConnected.
162 } else {
163 DLOG(ERROR) << "IPC SocketStream_Connect failed.";
164 OnClosed();
168 void IPCWebSocketStreamHandleBridge::DoClose() {
169 child_thread_->Send(new SocketStreamHostMsg_Close(socket_id_));
170 Release();
173 SocketStreamDispatcher::SocketStreamDispatcher() {
176 /* static */
177 webkit_glue::WebSocketStreamHandleBridge*
178 SocketStreamDispatcher::CreateBridge(
179 WebKit::WebSocketStreamHandle* handle,
180 webkit_glue::WebSocketStreamHandleDelegate* delegate) {
181 return new IPCWebSocketStreamHandleBridge(
182 ChildThread::current(), handle, delegate);
185 bool SocketStreamDispatcher::OnMessageReceived(const IPC::Message& msg) {
186 bool handled = true;
187 IPC_BEGIN_MESSAGE_MAP(SocketStreamDispatcher, msg)
188 IPC_MESSAGE_HANDLER(SocketStreamMsg_Connected, OnConnected)
189 IPC_MESSAGE_HANDLER(SocketStreamMsg_SentData, OnSentData)
190 IPC_MESSAGE_HANDLER(SocketStreamMsg_ReceivedData, OnReceivedData)
191 IPC_MESSAGE_HANDLER(SocketStreamMsg_Closed, OnClosed)
192 IPC_MESSAGE_UNHANDLED(handled = false)
193 IPC_END_MESSAGE_MAP()
194 return handled;
197 void SocketStreamDispatcher::OnConnected(int socket_id,
198 int max_pending_send_allowed) {
199 DVLOG(1) << "SocketStreamDispatcher::OnConnected socket_id=" << socket_id
200 << " max_pending_send_allowed=" << max_pending_send_allowed;
201 IPCWebSocketStreamHandleBridge* bridge =
202 IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
203 if (bridge)
204 bridge->OnConnected(max_pending_send_allowed);
205 else
206 DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id;
209 void SocketStreamDispatcher::OnSentData(int socket_id, int amount_sent) {
210 IPCWebSocketStreamHandleBridge* bridge =
211 IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
212 if (bridge)
213 bridge->OnSentData(amount_sent);
214 else
215 DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id;
218 void SocketStreamDispatcher::OnReceivedData(
219 int socket_id, const std::vector<char>& data) {
220 IPCWebSocketStreamHandleBridge* bridge =
221 IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
222 if (bridge)
223 bridge->OnReceivedData(data);
224 else
225 DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id;
228 void SocketStreamDispatcher::OnClosed(int socket_id) {
229 IPCWebSocketStreamHandleBridge* bridge =
230 IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
231 if (bridge)
232 bridge->OnClosed();
233 else
234 DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id;
237 } // namespace content