Make castv2 performance test work.
[chromium-blink-merge.git] / chrome / browser / devtools / device / android_web_socket.cc
blob84eea201d2b557555dc1ca2538f57e0e1cdef57b
1 // Copyright 2014 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 "base/memory/weak_ptr.h"
6 #include "base/message_loop/message_loop.h"
7 #include "base/rand_util.h"
8 #include "chrome/browser/devtools/device/android_device_manager.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "net/base/io_buffer.h"
11 #include "net/base/net_errors.h"
12 #include "net/server/web_socket_encoder.h"
13 #include "net/socket/stream_socket.h"
15 using content::BrowserThread;
16 using net::WebSocket;
18 namespace {
20 const int kBufferSize = 16 * 1024;
22 } // namespace
24 class AndroidDeviceManager::AndroidWebSocket::WebSocketImpl {
25 public:
26 WebSocketImpl(scoped_refptr<base::MessageLoopProxy> response_message_loop,
27 base::WeakPtr<AndroidWebSocket> weak_socket,
28 const std::string& extensions,
29 scoped_ptr<net::StreamSocket> socket)
30 : response_message_loop_(response_message_loop),
31 weak_socket_(weak_socket),
32 socket_(socket.Pass()),
33 encoder_(net::WebSocketEncoder::CreateClient(extensions)) {
34 thread_checker_.DetachFromThread();
37 void StartListening() {
38 DCHECK(thread_checker_.CalledOnValidThread());
39 DCHECK(socket_);
40 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
41 Read(buffer);
44 void SendFrame(const std::string& message) {
45 DCHECK(thread_checker_.CalledOnValidThread());
46 if (!socket_)
47 return;
48 int mask = base::RandInt(0, 0x7FFFFFFF);
49 std::string encoded_frame;
50 encoder_->EncodeFrame(message, mask, &encoded_frame);
51 request_buffer_ += encoded_frame;
52 if (request_buffer_.length() == encoded_frame.length())
53 SendPendingRequests(0);
56 private:
57 void Read(scoped_refptr<net::IOBuffer> response_buffer) {
58 int result = socket_->Read(
59 response_buffer.get(),
60 kBufferSize,
61 base::Bind(&WebSocketImpl::OnBytesRead,
62 base::Unretained(this), response_buffer));
63 if (result != net::ERR_IO_PENDING)
64 OnBytesRead(response_buffer, result);
67 void OnBytesRead(scoped_refptr<net::IOBuffer> response_buffer, int result) {
68 DCHECK(thread_checker_.CalledOnValidThread());
69 if (result <= 0) {
70 Disconnect();
71 return;
73 response_buffer_.append(response_buffer->data(), result);
75 int bytes_consumed;
76 std::string output;
77 WebSocket::ParseResult parse_result = encoder_->DecodeFrame(
78 response_buffer_, &bytes_consumed, &output);
80 while (parse_result == WebSocket::FRAME_OK) {
81 response_buffer_ = response_buffer_.substr(bytes_consumed);
82 response_message_loop_->PostTask(
83 FROM_HERE,
84 base::Bind(&AndroidWebSocket::OnFrameRead, weak_socket_, output));
85 parse_result = encoder_->DecodeFrame(
86 response_buffer_, &bytes_consumed, &output);
89 if (parse_result == WebSocket::FRAME_ERROR ||
90 parse_result == WebSocket::FRAME_CLOSE) {
91 Disconnect();
92 return;
94 Read(response_buffer);
97 void SendPendingRequests(int result) {
98 DCHECK(thread_checker_.CalledOnValidThread());
99 if (result < 0) {
100 Disconnect();
101 return;
103 request_buffer_ = request_buffer_.substr(result);
104 if (request_buffer_.empty())
105 return;
107 scoped_refptr<net::StringIOBuffer> buffer =
108 new net::StringIOBuffer(request_buffer_);
109 result = socket_->Write(buffer.get(), buffer->size(),
110 base::Bind(&WebSocketImpl::SendPendingRequests,
111 base::Unretained(this)));
112 if (result != net::ERR_IO_PENDING)
113 SendPendingRequests(result);
116 void Disconnect() {
117 DCHECK(thread_checker_.CalledOnValidThread());
118 socket_.reset();
119 response_message_loop_->PostTask(
120 FROM_HERE,
121 base::Bind(&AndroidWebSocket::OnSocketClosed, weak_socket_));
124 scoped_refptr<base::MessageLoopProxy> response_message_loop_;
125 base::WeakPtr<AndroidWebSocket> weak_socket_;
126 scoped_ptr<net::StreamSocket> socket_;
127 scoped_ptr<net::WebSocketEncoder> encoder_;
128 std::string response_buffer_;
129 std::string request_buffer_;
130 base::ThreadChecker thread_checker_;
131 DISALLOW_COPY_AND_ASSIGN(WebSocketImpl);
134 AndroidDeviceManager::AndroidWebSocket::AndroidWebSocket(
135 scoped_refptr<Device> device,
136 const std::string& socket_name,
137 const std::string& url,
138 Delegate* delegate)
139 : device_(device.get()),
140 socket_impl_(nullptr),
141 delegate_(delegate),
142 weak_factory_(this) {
143 DCHECK_CURRENTLY_ON(BrowserThread::UI);
144 DCHECK(delegate_);
145 DCHECK(device_);
146 device_->sockets_.insert(this);
147 device_->HttpUpgrade(
148 socket_name, url, net::WebSocketEncoder::kClientExtensions,
149 base::Bind(&AndroidWebSocket::Connected, weak_factory_.GetWeakPtr()));
152 AndroidDeviceManager::AndroidWebSocket::~AndroidWebSocket() {
153 DCHECK_CURRENTLY_ON(BrowserThread::UI);
154 Terminate();
157 void AndroidDeviceManager::AndroidWebSocket::SendFrame(
158 const std::string& message) {
159 DCHECK_CURRENTLY_ON(BrowserThread::UI);
160 DCHECK(socket_impl_);
161 DCHECK(device_);
162 device_->message_loop_proxy_->PostTask(
163 FROM_HERE,
164 base::Bind(&WebSocketImpl::SendFrame,
165 base::Unretained(socket_impl_), message));
168 void AndroidDeviceManager::AndroidWebSocket::Connected(
169 int result,
170 const std::string& extensions,
171 scoped_ptr<net::StreamSocket> socket) {
172 DCHECK_CURRENTLY_ON(BrowserThread::UI);
173 if (result != net::OK || !socket.get()) {
174 OnSocketClosed();
175 return;
177 socket_impl_ = new WebSocketImpl(base::MessageLoopProxy::current(),
178 weak_factory_.GetWeakPtr(),
179 extensions,
180 socket.Pass());
181 device_->message_loop_proxy_->PostTask(
182 FROM_HERE,
183 base::Bind(&WebSocketImpl::StartListening,
184 base::Unretained(socket_impl_)));
185 delegate_->OnSocketOpened();
188 void AndroidDeviceManager::AndroidWebSocket::OnFrameRead(
189 const std::string& message) {
190 DCHECK_CURRENTLY_ON(BrowserThread::UI);
191 delegate_->OnFrameRead(message);
194 void AndroidDeviceManager::AndroidWebSocket::OnSocketClosed() {
195 DCHECK_CURRENTLY_ON(BrowserThread::UI);
196 Terminate();
197 delegate_->OnSocketClosed();
200 void AndroidDeviceManager::AndroidWebSocket::Terminate() {
201 DCHECK_CURRENTLY_ON(BrowserThread::UI);
202 if (socket_impl_) {
203 DCHECK(device_);
204 device_->message_loop_proxy_->DeleteSoon(FROM_HERE, socket_impl_);
205 socket_impl_ = nullptr;
207 if (device_) {
208 device_->sockets_.erase(this);
209 device_ = nullptr;
213 AndroidDeviceManager::AndroidWebSocket*
214 AndroidDeviceManager::Device::CreateWebSocket(
215 const std::string& socket_name,
216 const std::string& url,
217 AndroidWebSocket::Delegate* delegate) {
218 return new AndroidWebSocket(this, socket_name, url, delegate);