Files.app: Provide detailed change information on onDirectoryChanged event
[chromium-blink-merge.git] / device / bluetooth / bluetooth_socket_net.cc
blob8007d77dca33a8792c2adda8302349a7a94fe80d
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 "device/bluetooth/bluetooth_socket_net.h"
7 #include <queue>
8 #include <string>
10 #include "base/logging.h"
11 #include "base/memory/linked_ptr.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/sequenced_task_runner.h"
15 #include "base/threading/thread_restrictions.h"
16 #include "device/bluetooth/bluetooth_socket.h"
17 #include "device/bluetooth/bluetooth_socket_thread.h"
18 #include "net/base/io_buffer.h"
19 #include "net/base/net_errors.h"
21 namespace {
23 const char kSocketNotConnected[] = "Socket is not connected.";
25 static void DeactivateSocket(
26 const scoped_refptr<device::BluetoothSocketThread>& socket_thread) {
27 socket_thread->OnSocketDeactivate();
30 } // namespace
32 namespace device {
34 BluetoothSocketNet::WriteRequest::WriteRequest()
35 : buffer_size(0) {}
37 BluetoothSocketNet::WriteRequest::~WriteRequest() {}
39 BluetoothSocketNet::BluetoothSocketNet(
40 scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
41 scoped_refptr<BluetoothSocketThread> socket_thread,
42 net::NetLog* net_log,
43 const net::NetLog::Source& source)
44 : ui_task_runner_(ui_task_runner),
45 socket_thread_(socket_thread),
46 net_log_(net_log),
47 source_(source) {
48 DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
49 socket_thread_->OnSocketActivate();
52 BluetoothSocketNet::~BluetoothSocketNet() {
53 DCHECK(tcp_socket_.get() == NULL);
54 ui_task_runner_->PostTask(FROM_HERE,
55 base::Bind(&DeactivateSocket, socket_thread_));
58 void BluetoothSocketNet::Close() {
59 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
60 socket_thread_->task_runner()->PostTask(
61 FROM_HERE, base::Bind(&BluetoothSocketNet::DoClose, this));
64 void BluetoothSocketNet::Disconnect(
65 const base::Closure& success_callback) {
66 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
67 socket_thread_->task_runner()->PostTask(
68 FROM_HERE,
69 base::Bind(
70 &BluetoothSocketNet::DoDisconnect,
71 this,
72 base::Bind(&BluetoothSocketNet::PostSuccess,
73 this,
74 success_callback)));
77 void BluetoothSocketNet::Receive(
78 int buffer_size,
79 const ReceiveCompletionCallback& success_callback,
80 const ReceiveErrorCompletionCallback& error_callback) {
81 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
82 socket_thread_->task_runner()->PostTask(
83 FROM_HERE,
84 base::Bind(
85 &BluetoothSocketNet::DoReceive,
86 this,
87 buffer_size,
88 base::Bind(&BluetoothSocketNet::PostReceiveCompletion,
89 this,
90 success_callback),
91 base::Bind(&BluetoothSocketNet::PostReceiveErrorCompletion,
92 this,
93 error_callback)));
96 void BluetoothSocketNet::Send(
97 scoped_refptr<net::IOBuffer> buffer,
98 int buffer_size,
99 const SendCompletionCallback& success_callback,
100 const ErrorCompletionCallback& error_callback) {
101 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
102 socket_thread_->task_runner()->PostTask(
103 FROM_HERE,
104 base::Bind(
105 &BluetoothSocketNet::DoSend,
106 this,
107 buffer,
108 buffer_size,
109 base::Bind(&BluetoothSocketNet::PostSendCompletion,
110 this,
111 success_callback),
112 base::Bind(&BluetoothSocketNet::PostErrorCompletion,
113 this,
114 error_callback)));
117 void BluetoothSocketNet::ResetData() {
120 void BluetoothSocketNet::ResetTCPSocket() {
121 tcp_socket_.reset(new net::TCPSocket(net_log_, source_));
124 void BluetoothSocketNet::SetTCPSocket(scoped_ptr<net::TCPSocket> tcp_socket) {
125 tcp_socket_ = tcp_socket.Pass();
128 void BluetoothSocketNet::PostSuccess(const base::Closure& callback) {
129 ui_task_runner_->PostTask(FROM_HERE, callback);
132 void BluetoothSocketNet::PostErrorCompletion(
133 const ErrorCompletionCallback& callback,
134 const std::string& error) {
135 ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, error));
138 void BluetoothSocketNet::DoClose() {
139 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
140 base::ThreadRestrictions::AssertIOAllowed();
142 if (tcp_socket_) {
143 tcp_socket_->Close();
144 tcp_socket_.reset(NULL);
147 // Note: Closing |tcp_socket_| above released all potential pending
148 // Send/Receive operations, so we can no safely release the state associated
149 // to those pending operations.
150 read_buffer_ = NULL;
151 std::queue<linked_ptr<WriteRequest> > empty;
152 std::swap(write_queue_, empty);
154 ResetData();
157 void BluetoothSocketNet::DoDisconnect(const base::Closure& callback) {
158 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
159 base::ThreadRestrictions::AssertIOAllowed();
161 DoClose();
162 callback.Run();
165 void BluetoothSocketNet::DoReceive(
166 int buffer_size,
167 const ReceiveCompletionCallback& success_callback,
168 const ReceiveErrorCompletionCallback& error_callback) {
169 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
170 base::ThreadRestrictions::AssertIOAllowed();
172 if (!tcp_socket_) {
173 error_callback.Run(BluetoothSocket::kDisconnected, kSocketNotConnected);
174 return;
177 // Only one pending read at a time
178 if (read_buffer_.get()) {
179 error_callback.Run(BluetoothSocket::kIOPending,
180 net::ErrorToString(net::ERR_IO_PENDING));
181 return;
184 scoped_refptr<net::IOBufferWithSize> buffer(
185 new net::IOBufferWithSize(buffer_size));
186 int read_result =
187 tcp_socket_->Read(buffer.get(),
188 buffer->size(),
189 base::Bind(&BluetoothSocketNet::OnSocketReadComplete,
190 this,
191 success_callback,
192 error_callback));
194 read_buffer_ = buffer;
195 if (read_result != net::ERR_IO_PENDING)
196 OnSocketReadComplete(success_callback, error_callback, read_result);
199 void BluetoothSocketNet::OnSocketReadComplete(
200 const ReceiveCompletionCallback& success_callback,
201 const ReceiveErrorCompletionCallback& error_callback,
202 int read_result) {
203 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
204 base::ThreadRestrictions::AssertIOAllowed();
206 scoped_refptr<net::IOBufferWithSize> buffer;
207 buffer.swap(read_buffer_);
208 if (read_result > 0) {
209 success_callback.Run(read_result, buffer);
210 } else if (read_result == net::OK ||
211 read_result == net::ERR_CONNECTION_CLOSED ||
212 read_result == net::ERR_CONNECTION_RESET) {
213 error_callback.Run(BluetoothSocket::kDisconnected,
214 net::ErrorToString(read_result));
215 } else {
216 error_callback.Run(BluetoothSocket::kSystemError,
217 net::ErrorToString(read_result));
221 void BluetoothSocketNet::DoSend(
222 scoped_refptr<net::IOBuffer> buffer,
223 int buffer_size,
224 const SendCompletionCallback& success_callback,
225 const ErrorCompletionCallback& error_callback) {
226 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
227 base::ThreadRestrictions::AssertIOAllowed();
229 if (!tcp_socket_) {
230 error_callback.Run(kSocketNotConnected);
231 return;
234 linked_ptr<WriteRequest> request(new WriteRequest());
235 request->buffer = buffer;
236 request->buffer_size = buffer_size;
237 request->success_callback = success_callback;
238 request->error_callback = error_callback;
240 write_queue_.push(request);
241 if (write_queue_.size() == 1) {
242 SendFrontWriteRequest();
246 void BluetoothSocketNet::SendFrontWriteRequest() {
247 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
248 base::ThreadRestrictions::AssertIOAllowed();
250 if (!tcp_socket_)
251 return;
253 if (write_queue_.size() == 0)
254 return;
256 linked_ptr<WriteRequest> request = write_queue_.front();
257 net::CompletionCallback callback =
258 base::Bind(&BluetoothSocketNet::OnSocketWriteComplete,
259 this,
260 request->success_callback,
261 request->error_callback);
262 int send_result =
263 tcp_socket_->Write(request->buffer, request->buffer_size, callback);
264 if (send_result != net::ERR_IO_PENDING) {
265 callback.Run(send_result);
269 void BluetoothSocketNet::OnSocketWriteComplete(
270 const SendCompletionCallback& success_callback,
271 const ErrorCompletionCallback& error_callback,
272 int send_result) {
273 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
274 base::ThreadRestrictions::AssertIOAllowed();
276 write_queue_.pop();
278 if (send_result >= net::OK) {
279 success_callback.Run(send_result);
280 } else {
281 error_callback.Run(net::ErrorToString(send_result));
284 // Don't call directly to avoid potentail large recursion.
285 socket_thread_->task_runner()->PostNonNestableTask(
286 FROM_HERE,
287 base::Bind(&BluetoothSocketNet::SendFrontWriteRequest, this));
290 void BluetoothSocketNet::PostReceiveCompletion(
291 const ReceiveCompletionCallback& callback,
292 int io_buffer_size,
293 scoped_refptr<net::IOBuffer> io_buffer) {
294 ui_task_runner_->PostTask(FROM_HERE,
295 base::Bind(callback, io_buffer_size, io_buffer));
298 void BluetoothSocketNet::PostReceiveErrorCompletion(
299 const ReceiveErrorCompletionCallback& callback,
300 ErrorReason reason,
301 const std::string& error_message) {
302 ui_task_runner_->PostTask(FROM_HERE,
303 base::Bind(callback, reason, error_message));
306 void BluetoothSocketNet::PostSendCompletion(
307 const SendCompletionCallback& callback,
308 int bytes_written) {
309 ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, bytes_written));
312 } // namespace device