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

Side by Side Diff: device/bluetooth/bluetooth_socket_net.cc

Issue 267633003: Reimplement BluetoothSocketChromeOS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review comments #1 Created 6 years, 7 months 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
OLDNEW
(Empty)
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.
4
5 #include "device/bluetooth/bluetooth_socket_net.h"
6
7 #include <string>
8
9 #include "base/logging.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/sequenced_task_runner.h"
12 #include "base/threading/thread_restrictions.h"
13 #include "device/bluetooth/bluetooth_socket.h"
14 #include "device/bluetooth/bluetooth_socket_thread.h"
15 #include "net/base/io_buffer.h"
16 #include "net/base/net_errors.h"
17
18 namespace {
19
20 const char kSocketNotConnected[] = "Socket is not connected.";
21
22 static void DeactivateSocket(
23 const scoped_refptr<device::BluetoothSocketThread>& socket_thread) {
24 socket_thread->OnSocketDeactivate();
25 }
26
27 } // namespace
28
29 namespace device {
30
31 // static
32 scoped_refptr<BluetoothSocketNet>
33 BluetoothSocketNet::CreateBluetoothSocket(
34 scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
35 scoped_refptr<BluetoothSocketThread> socket_thread,
36 net::NetLog* net_log,
37 const net::NetLog::Source& source) {
38 DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
39
40 return make_scoped_refptr(
41 new BluetoothSocketNet(ui_task_runner, socket_thread, net_log, source));
42 }
43
44 BluetoothSocketNet::WriteRequest::WriteRequest()
45 : buffer_size(0) {}
46
47 BluetoothSocketNet::WriteRequest::~WriteRequest() {}
48
49 BluetoothSocketNet::BluetoothSocketNet(
50 scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
51 scoped_refptr<BluetoothSocketThread> socket_thread,
52 net::NetLog* net_log,
53 const net::NetLog::Source& source)
54 : ui_task_runner_(ui_task_runner),
55 socket_thread_(socket_thread),
56 net_log_(net_log),
57 source_(source) {
58 DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
59 socket_thread_->OnSocketActivate();
60 }
61
62 BluetoothSocketNet::~BluetoothSocketNet() {
63 DCHECK(tcp_socket_.get() == NULL);
64 ui_task_runner_->PostTask(FROM_HERE,
65 base::Bind(&DeactivateSocket, socket_thread_));
66 }
67
68 void BluetoothSocketNet::Close() {
69 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
70 socket_thread_->task_runner()->PostTask(
71 FROM_HERE, base::Bind(&BluetoothSocketNet::DoClose, this));
72 }
73
74 void BluetoothSocketNet::Disconnect(
75 const base::Closure& success_callback) {
76 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
77 socket_thread_->task_runner()->PostTask(
78 FROM_HERE,
79 base::Bind(
80 &BluetoothSocketNet::DoDisconnect,
81 this,
82 base::Bind(&BluetoothSocketNet::PostSuccess,
83 this,
84 success_callback)));
85 }
86
87 void BluetoothSocketNet::Receive(
88 int buffer_size,
89 const ReceiveCompletionCallback& success_callback,
90 const ReceiveErrorCompletionCallback& error_callback) {
91 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
92 socket_thread_->task_runner()->PostTask(
93 FROM_HERE,
94 base::Bind(
95 &BluetoothSocketNet::DoReceive,
96 this,
97 buffer_size,
98 base::Bind(&BluetoothSocketNet::PostReceiveCompletion,
99 this,
100 success_callback),
101 base::Bind(&BluetoothSocketNet::PostReceiveErrorCompletion,
102 this,
103 error_callback)));
104 }
105
106 void BluetoothSocketNet::Send(
107 scoped_refptr<net::IOBuffer> buffer,
108 int buffer_size,
109 const SendCompletionCallback& success_callback,
110 const ErrorCompletionCallback& error_callback) {
111 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
112 socket_thread_->task_runner()->PostTask(
113 FROM_HERE,
114 base::Bind(
115 &BluetoothSocketNet::DoSend,
116 this,
117 buffer,
118 buffer_size,
119 base::Bind(&BluetoothSocketNet::PostSendCompletion,
120 this,
121 success_callback),
122 base::Bind(&BluetoothSocketNet::PostErrorCompletion,
123 this,
124 error_callback)));
125 }
126
127 void BluetoothSocketNet::ResetData() {
128 }
129
130 void BluetoothSocketNet::ResetTCPSocket() {
131 tcp_socket_.reset(new net::TCPSocket(net_log_, source_));
132 }
133
134 void BluetoothSocketNet::SetTCPSocket(scoped_ptr<net::TCPSocket> tcp_socket) {
135 tcp_socket_ = tcp_socket.Pass();
136 }
137
138 void BluetoothSocketNet::PostSuccess(const base::Closure& callback) {
139 ui_task_runner_->PostTask(FROM_HERE, callback);
140 }
141
142 void BluetoothSocketNet::PostErrorCompletion(
143 const ErrorCompletionCallback& callback,
144 const std::string& error) {
145 ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, error));
146 }
147
148 void BluetoothSocketNet::DoClose() {
149 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
150 base::ThreadRestrictions::AssertIOAllowed();
151
152 if (tcp_socket_) {
153 tcp_socket_->Close();
154 tcp_socket_.reset(NULL);
155 }
156
157 // Note: Closing |tcp_socket_| above released all potential pending
158 // Send/Receive operations, so we can no safely release the state associated
159 // to those pending operations.
160 read_buffer_ = NULL;
161 std::queue<linked_ptr<WriteRequest> > empty;
162 write_queue_.swap(empty);
163
164 ResetData();
165 }
166
167 void BluetoothSocketNet::DoDisconnect(const base::Closure& callback) {
168 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
169 base::ThreadRestrictions::AssertIOAllowed();
170
171 DoClose();
172 callback.Run();
173 }
174
175 void BluetoothSocketNet::DoReceive(
176 int buffer_size,
177 const ReceiveCompletionCallback& success_callback,
178 const ReceiveErrorCompletionCallback& error_callback) {
179 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
180 base::ThreadRestrictions::AssertIOAllowed();
181
182 if (!tcp_socket_) {
183 error_callback.Run(BluetoothSocket::kDisconnected, kSocketNotConnected);
184 return;
185 }
186
187 // Only one pending read at a time
188 if (read_buffer_.get()) {
189 error_callback.Run(BluetoothSocket::kIOPending,
190 net::ErrorToString(net::ERR_IO_PENDING));
191 return;
192 }
193
194 scoped_refptr<net::IOBufferWithSize> buffer(
195 new net::IOBufferWithSize(buffer_size));
196 int read_result =
197 tcp_socket_->Read(buffer.get(),
198 buffer->size(),
199 base::Bind(&BluetoothSocketNet::OnSocketReadComplete,
200 this,
201 success_callback,
202 error_callback));
203
204 if (read_result > 0) {
205 success_callback.Run(read_result, buffer);
206 } else if (read_result == net::OK ||
207 read_result == net::ERR_CONNECTION_CLOSED) {
208 error_callback.Run(BluetoothSocket::kDisconnected,
209 net::ErrorToString(net::ERR_CONNECTION_CLOSED));
210 } else if (read_result == net::ERR_IO_PENDING) {
211 read_buffer_ = buffer;
212 } else {
213 error_callback.Run(BluetoothSocket::kSystemError,
214 net::ErrorToString(read_result));
215 }
216 }
217
218 void BluetoothSocketNet::OnSocketReadComplete(
219 const ReceiveCompletionCallback& success_callback,
220 const ReceiveErrorCompletionCallback& error_callback,
221 int read_result) {
222 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
223 base::ThreadRestrictions::AssertIOAllowed();
224
225 scoped_refptr<net::IOBufferWithSize> buffer;
226 buffer.swap(read_buffer_);
227 if (read_result > 0) {
228 success_callback.Run(read_result, buffer);
229 } else if (read_result == net::OK ||
230 read_result == net::ERR_CONNECTION_CLOSED) {
231 error_callback.Run(BluetoothSocket::kDisconnected,
232 net::ErrorToString(net::ERR_CONNECTION_CLOSED));
233 } else {
234 error_callback.Run(BluetoothSocket::kSystemError,
235 net::ErrorToString(read_result));
236 }
237 }
238
239 void BluetoothSocketNet::DoSend(
240 scoped_refptr<net::IOBuffer> buffer,
241 int buffer_size,
242 const SendCompletionCallback& success_callback,
243 const ErrorCompletionCallback& error_callback) {
244 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
245 base::ThreadRestrictions::AssertIOAllowed();
246
247 if (!tcp_socket_) {
248 error_callback.Run(kSocketNotConnected);
249 return;
250 }
251
252 linked_ptr<WriteRequest> request(new WriteRequest());
253 request->buffer = buffer;
254 request->buffer_size = buffer_size;
255 request->success_callback = success_callback;
256 request->error_callback = error_callback;
257
258 write_queue_.push(request);
259 if (write_queue_.size() == 1) {
260 SendFrontWriteRequest();
261 }
262 }
263
264 void BluetoothSocketNet::SendFrontWriteRequest() {
265 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
266 base::ThreadRestrictions::AssertIOAllowed();
267
268 if (!tcp_socket_)
269 return;
270
271 if (write_queue_.size() == 0)
272 return;
273
274 linked_ptr<WriteRequest> request = write_queue_.front();
275 net::CompletionCallback callback =
276 base::Bind(&BluetoothSocketNet::OnSocketWriteComplete,
277 this,
278 request->success_callback,
279 request->error_callback);
280 int send_result =
281 tcp_socket_->Write(request->buffer, request->buffer_size, callback);
282 if (send_result != net::ERR_IO_PENDING) {
283 callback.Run(send_result);
284 }
285 }
286
287 void BluetoothSocketNet::OnSocketWriteComplete(
288 const SendCompletionCallback& success_callback,
289 const ErrorCompletionCallback& error_callback,
290 int send_result) {
291 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
292 base::ThreadRestrictions::AssertIOAllowed();
293
294 write_queue_.pop();
295
296 if (send_result >= net::OK) {
297 success_callback.Run(send_result);
298 } else {
299 error_callback.Run(net::ErrorToString(send_result));
300 }
301
302 // Don't call directly to avoid potentail large recursion.
303 socket_thread_->task_runner()->PostNonNestableTask(
304 FROM_HERE,
305 base::Bind(&BluetoothSocketNet::SendFrontWriteRequest, this));
306 }
307
308 void BluetoothSocketNet::PostReceiveCompletion(
309 const ReceiveCompletionCallback& callback,
310 int io_buffer_size,
311 scoped_refptr<net::IOBuffer> io_buffer) {
312 ui_task_runner_->PostTask(FROM_HERE,
313 base::Bind(callback, io_buffer_size, io_buffer));
314 }
315
316 void BluetoothSocketNet::PostReceiveErrorCompletion(
317 const ReceiveErrorCompletionCallback& callback,
318 ErrorReason reason,
319 const std::string& error_message) {
320 ui_task_runner_->PostTask(FROM_HERE,
321 base::Bind(callback, reason, error_message));
322 }
323
324 void BluetoothSocketNet::PostSendCompletion(
325 const SendCompletionCallback& callback,
326 int bytes_written) {
327 ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, bytes_written));
328 }
329
330 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698