Fix "#if defined(DEBUG)" statements
[chromium-blink-merge.git] / device / serial / serial_io_handler.cc
bloba9cb52f85dc918ae4809110bd9e14a615093004c
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/serial/serial_io_handler.h"
7 #include "base/bind.h"
8 #include "base/files/file_path.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_util.h"
12 namespace device {
14 SerialIoHandler::SerialIoHandler(
15 scoped_refptr<base::MessageLoopProxy> file_thread_message_loop,
16 scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop)
17 : file_thread_message_loop_(file_thread_message_loop),
18 ui_thread_message_loop_(ui_thread_message_loop) {
21 SerialIoHandler::~SerialIoHandler() {
22 DCHECK(CalledOnValidThread());
23 Close();
26 void SerialIoHandler::Open(const std::string& port,
27 const OpenCompleteCallback& callback) {
28 DCHECK(CalledOnValidThread());
29 DCHECK(open_complete_.is_null());
30 open_complete_ = callback;
31 DCHECK(file_thread_message_loop_.get());
32 DCHECK(ui_thread_message_loop_.get());
33 RequestAccess(port, file_thread_message_loop_, ui_thread_message_loop_);
36 void SerialIoHandler::RequestAccess(
37 const std::string& port,
38 scoped_refptr<base::MessageLoopProxy> file_message_loop,
39 scoped_refptr<base::MessageLoopProxy> ui_message_loop) {
40 OnRequestAccessComplete(port, true /* success */);
43 void SerialIoHandler::OnRequestAccessComplete(const std::string& port,
44 bool success) {
45 DCHECK(CalledOnValidThread());
46 if (success) {
47 DCHECK(file_thread_message_loop_.get());
48 file_thread_message_loop_->PostTask(
49 FROM_HERE,
50 base::Bind(&SerialIoHandler::StartOpen,
51 this,
52 port,
53 base::MessageLoopProxy::current()));
54 return;
55 } else {
56 DCHECK(!open_complete_.is_null());
57 OpenCompleteCallback callback = open_complete_;
58 open_complete_.Reset();
59 callback.Run(false);
60 return;
64 void SerialIoHandler::StartOpen(
65 const std::string& port,
66 scoped_refptr<base::MessageLoopProxy> io_message_loop) {
67 DCHECK(!open_complete_.is_null());
68 DCHECK(file_thread_message_loop_->RunsTasksOnCurrentThread());
69 DCHECK(!file_.IsValid());
70 // It's the responsibility of the API wrapper around SerialIoHandler to
71 // validate the supplied path against the set of valid port names, and
72 // it is a reasonable assumption that serial port names are ASCII.
73 DCHECK(base::IsStringASCII(port));
74 base::FilePath path(base::FilePath::FromUTF8Unsafe(MaybeFixUpPortName(port)));
75 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
76 base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_WRITE |
77 base::File::FLAG_EXCLUSIVE_WRITE | base::File::FLAG_ASYNC |
78 base::File::FLAG_TERMINAL_DEVICE;
79 base::File file(path, flags);
80 io_message_loop->PostTask(
81 FROM_HERE,
82 base::Bind(&SerialIoHandler::FinishOpen, this, Passed(file.Pass())));
85 void SerialIoHandler::FinishOpen(base::File file) {
86 DCHECK(CalledOnValidThread());
87 DCHECK(!open_complete_.is_null());
88 OpenCompleteCallback callback = open_complete_;
89 open_complete_.Reset();
91 if (!file.IsValid()) {
92 callback.Run(false);
93 return;
96 file_ = file.Pass();
98 bool success = PostOpen();
99 if (!success)
100 Close();
101 callback.Run(success);
104 bool SerialIoHandler::PostOpen() {
105 return true;
108 void SerialIoHandler::Close() {
109 if (file_.IsValid()) {
110 DCHECK(file_thread_message_loop_.get());
111 file_thread_message_loop_->PostTask(
112 FROM_HERE, base::Bind(&SerialIoHandler::DoClose, Passed(file_.Pass())));
116 // static
117 void SerialIoHandler::DoClose(base::File port) {
118 // port closed by destructor.
121 void SerialIoHandler::Read(scoped_ptr<WritableBuffer> buffer) {
122 DCHECK(CalledOnValidThread());
123 DCHECK(!IsReadPending());
124 pending_read_buffer_ = buffer.Pass();
125 read_canceled_ = false;
126 AddRef();
127 ReadImpl();
130 void SerialIoHandler::Write(scoped_ptr<ReadOnlyBuffer> buffer) {
131 DCHECK(CalledOnValidThread());
132 DCHECK(!IsWritePending());
133 pending_write_buffer_ = buffer.Pass();
134 write_canceled_ = false;
135 AddRef();
136 WriteImpl();
139 void SerialIoHandler::ReadCompleted(int bytes_read,
140 serial::ReceiveError error) {
141 DCHECK(CalledOnValidThread());
142 DCHECK(IsReadPending());
143 scoped_ptr<WritableBuffer> pending_read_buffer = pending_read_buffer_.Pass();
144 if (error == serial::RECEIVE_ERROR_NONE) {
145 pending_read_buffer->Done(bytes_read);
146 } else {
147 pending_read_buffer->DoneWithError(bytes_read, error);
149 Release();
152 void SerialIoHandler::WriteCompleted(int bytes_written,
153 serial::SendError error) {
154 DCHECK(CalledOnValidThread());
155 DCHECK(IsWritePending());
156 scoped_ptr<ReadOnlyBuffer> pending_write_buffer =
157 pending_write_buffer_.Pass();
158 if (error == serial::SEND_ERROR_NONE) {
159 pending_write_buffer->Done(bytes_written);
160 } else {
161 pending_write_buffer->DoneWithError(bytes_written, error);
163 Release();
166 bool SerialIoHandler::IsReadPending() const {
167 DCHECK(CalledOnValidThread());
168 return pending_read_buffer_ != NULL;
171 bool SerialIoHandler::IsWritePending() const {
172 DCHECK(CalledOnValidThread());
173 return pending_write_buffer_ != NULL;
176 void SerialIoHandler::CancelRead(serial::ReceiveError reason) {
177 DCHECK(CalledOnValidThread());
178 if (IsReadPending() && !read_canceled_) {
179 read_canceled_ = true;
180 read_cancel_reason_ = reason;
181 CancelReadImpl();
185 void SerialIoHandler::CancelWrite(serial::SendError reason) {
186 DCHECK(CalledOnValidThread());
187 if (IsWritePending() && !write_canceled_) {
188 write_canceled_ = true;
189 write_cancel_reason_ = reason;
190 CancelWriteImpl();
194 void SerialIoHandler::QueueReadCompleted(int bytes_read,
195 serial::ReceiveError error) {
196 base::MessageLoop::current()->PostTask(
197 FROM_HERE,
198 base::Bind(&SerialIoHandler::ReadCompleted, this, bytes_read, error));
201 void SerialIoHandler::QueueWriteCompleted(int bytes_written,
202 serial::SendError error) {
203 base::MessageLoop::current()->PostTask(
204 FROM_HERE,
205 base::Bind(&SerialIoHandler::WriteCompleted, this, bytes_written, error));
208 } // namespace device