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

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: 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() {
armansito 2014/05/01 00:14:25 I would at least log something here, maybe VLOG(1)
keybuk 2014/05/01 00:24:09 NAK, this is just for subclasses - Win happens to
armansito 2014/05/01 00:54:17 sgtm
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(
168 const base::Closure& success_callback) {
169 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
170 base::ThreadRestrictions::AssertIOAllowed();
171
172 DoClose();
173 success_callback.Run();
174 }
175
176 void BluetoothSocketNet::DoReceive(
177 int buffer_size,
178 const ReceiveCompletionCallback& success_callback,
179 const ReceiveErrorCompletionCallback& error_callback) {
180 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
181 base::ThreadRestrictions::AssertIOAllowed();
182
183 if (!tcp_socket_) {
184 error_callback.Run(BluetoothSocket::kDisconnected, kSocketNotConnected);
185 return;
186 }
187
188 // Only one pending read at a time
189 if (read_buffer_.get()) {
190 error_callback.Run(BluetoothSocket::kIOPending,
191 net::ErrorToString(net::ERR_IO_PENDING));
192 return;
193 }
194
195 scoped_refptr<net::IOBufferWithSize> buffer(
196 new net::IOBufferWithSize(buffer_size));
197 int read_result =
198 tcp_socket_->Read(buffer.get(),
199 buffer->size(),
200 base::Bind(&BluetoothSocketNet::OnSocketReadComplete,
201 this,
202 success_callback,
203 error_callback));
204
205 if (read_result > 0) {
206 success_callback.Run(read_result, buffer);
207 } else if (read_result == net::OK ||
208 read_result == net::ERR_CONNECTION_CLOSED) {
209 error_callback.Run(BluetoothSocket::kDisconnected,
210 net::ErrorToString(net::ERR_CONNECTION_CLOSED));
211 } else if (read_result == net::ERR_IO_PENDING) {
212 read_buffer_ = buffer;
213 } else {
214 error_callback.Run(BluetoothSocket::kSystemError,
215 net::ErrorToString(read_result));
216 }
217 }
218
219 void BluetoothSocketNet::OnSocketReadComplete(
220 const ReceiveCompletionCallback& success_callback,
221 const ReceiveErrorCompletionCallback& error_callback,
222 int read_result) {
223 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
224 base::ThreadRestrictions::AssertIOAllowed();
225
226 scoped_refptr<net::IOBufferWithSize> buffer;
227 buffer.swap(read_buffer_);
228 if (read_result > 0) {
229 success_callback.Run(read_result, buffer);
230 } else if (read_result == net::OK ||
231 read_result == net::ERR_CONNECTION_CLOSED) {
232 error_callback.Run(BluetoothSocket::kDisconnected,
233 net::ErrorToString(net::ERR_CONNECTION_CLOSED));
234 } else {
235 error_callback.Run(BluetoothSocket::kSystemError,
236 net::ErrorToString(read_result));
237 }
238 }
239
240 void BluetoothSocketNet::DoSend(
241 scoped_refptr<net::IOBuffer> buffer,
242 int buffer_size,
243 const SendCompletionCallback& success_callback,
244 const ErrorCompletionCallback& error_callback) {
245 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
246 base::ThreadRestrictions::AssertIOAllowed();
247
248 if (!tcp_socket_) {
249 error_callback.Run(kSocketNotConnected);
250 return;
251 }
252
253 linked_ptr<WriteRequest> request(new WriteRequest());
254 request->buffer = buffer;
255 request->buffer_size = buffer_size;
256 request->success_callback = success_callback;
257 request->error_callback = error_callback;
258
259 write_queue_.push(request);
260 if (write_queue_.size() == 1) {
261 SendFrontWriteRequest();
262 }
263 }
264
265 void BluetoothSocketNet::SendFrontWriteRequest() {
266 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
267 base::ThreadRestrictions::AssertIOAllowed();
268
269 if (!tcp_socket_)
270 return;
271
272 if (write_queue_.size() == 0)
273 return;
274
275 linked_ptr<WriteRequest> request = write_queue_.front();
276 net::CompletionCallback callback =
277 base::Bind(&BluetoothSocketNet::OnSocketWriteComplete,
278 this,
279 request->success_callback,
280 request->error_callback);
281 int send_result =
282 tcp_socket_->Write(request->buffer, request->buffer_size, callback);
283 if (send_result != net::ERR_IO_PENDING) {
284 callback.Run(send_result);
285 }
286 }
287
288 void BluetoothSocketNet::OnSocketWriteComplete(
289 const SendCompletionCallback& success_callback,
290 const ErrorCompletionCallback& error_callback,
291 int send_result) {
292 DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
293 base::ThreadRestrictions::AssertIOAllowed();
294
295 write_queue_.pop();
296
297 if (send_result >= net::OK) {
298 success_callback.Run(send_result);
299 } else {
300 error_callback.Run(net::ErrorToString(send_result));
301 }
302
303 // Don't call directly to avoid potentail large recursion.
304 socket_thread_->task_runner()->PostNonNestableTask(
305 FROM_HERE,
306 base::Bind(&BluetoothSocketNet::SendFrontWriteRequest, this));
307 }
308
309 void BluetoothSocketNet::PostReceiveCompletion(
310 const ReceiveCompletionCallback& callback,
311 int io_buffer_size,
312 scoped_refptr<net::IOBuffer> io_buffer) {
313 ui_task_runner_->PostTask(FROM_HERE,
314 base::Bind(callback, io_buffer_size, io_buffer));
315 }
316
317 void BluetoothSocketNet::PostReceiveErrorCompletion(
318 const ReceiveErrorCompletionCallback& callback,
319 ErrorReason reason,
320 const std::string& error_message) {
321 ui_task_runner_->PostTask(FROM_HERE,
322 base::Bind(callback, reason, error_message));
323 }
324
325 void BluetoothSocketNet::PostSendCompletion(
326 const SendCompletionCallback& callback,
327 int bytes_written) {
328 ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, bytes_written));
329 }
330
331 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698