| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "device/serial/serial_io_handler.h" | 5 #include "device/serial/serial_io_handler.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 11 | 11 |
| 12 namespace device { | 12 namespace device { |
| 13 | 13 |
| 14 SerialIoHandler::SerialIoHandler( | 14 SerialIoHandler::SerialIoHandler( |
| 15 scoped_refptr<base::MessageLoopProxy> file_thread_message_loop, | 15 scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner, |
| 16 scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop) | 16 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) |
| 17 : file_thread_message_loop_(file_thread_message_loop), | 17 : file_thread_task_runner_(file_thread_task_runner), |
| 18 ui_thread_message_loop_(ui_thread_message_loop) { | 18 ui_thread_task_runner_(ui_thread_task_runner) { |
| 19 options_.bitrate = 9600; | 19 options_.bitrate = 9600; |
| 20 options_.data_bits = serial::DATA_BITS_EIGHT; | 20 options_.data_bits = serial::DATA_BITS_EIGHT; |
| 21 options_.parity_bit = serial::PARITY_BIT_NO; | 21 options_.parity_bit = serial::PARITY_BIT_NO; |
| 22 options_.stop_bits = serial::STOP_BITS_ONE; | 22 options_.stop_bits = serial::STOP_BITS_ONE; |
| 23 options_.cts_flow_control = false; | 23 options_.cts_flow_control = false; |
| 24 options_.has_cts_flow_control = true; | 24 options_.has_cts_flow_control = true; |
| 25 } | 25 } |
| 26 | 26 |
| 27 SerialIoHandler::~SerialIoHandler() { | 27 SerialIoHandler::~SerialIoHandler() { |
| 28 DCHECK(CalledOnValidThread()); | 28 DCHECK(CalledOnValidThread()); |
| 29 Close(); | 29 Close(); |
| 30 } | 30 } |
| 31 | 31 |
| 32 void SerialIoHandler::Open(const std::string& port, | 32 void SerialIoHandler::Open(const std::string& port, |
| 33 const serial::ConnectionOptions& options, | 33 const serial::ConnectionOptions& options, |
| 34 const OpenCompleteCallback& callback) { | 34 const OpenCompleteCallback& callback) { |
| 35 DCHECK(CalledOnValidThread()); | 35 DCHECK(CalledOnValidThread()); |
| 36 DCHECK(open_complete_.is_null()); | 36 DCHECK(open_complete_.is_null()); |
| 37 open_complete_ = callback; | 37 open_complete_ = callback; |
| 38 DCHECK(file_thread_message_loop_.get()); | 38 DCHECK(file_thread_task_runner_.get()); |
| 39 DCHECK(ui_thread_message_loop_.get()); | 39 DCHECK(ui_thread_task_runner_.get()); |
| 40 MergeConnectionOptions(options); | 40 MergeConnectionOptions(options); |
| 41 RequestAccess(port, file_thread_message_loop_, ui_thread_message_loop_); | 41 RequestAccess(port, file_thread_task_runner_, ui_thread_task_runner_); |
| 42 } | 42 } |
| 43 | 43 |
| 44 void SerialIoHandler::RequestAccess( | 44 void SerialIoHandler::RequestAccess( |
| 45 const std::string& port, | 45 const std::string& port, |
| 46 scoped_refptr<base::MessageLoopProxy> file_message_loop, | 46 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, |
| 47 scoped_refptr<base::MessageLoopProxy> ui_message_loop) { | 47 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
| 48 OnRequestAccessComplete(port, true /* success */); | 48 OnRequestAccessComplete(port, true /* success */); |
| 49 } | 49 } |
| 50 | 50 |
| 51 void SerialIoHandler::OnRequestAccessComplete(const std::string& port, | 51 void SerialIoHandler::OnRequestAccessComplete(const std::string& port, |
| 52 bool success) { | 52 bool success) { |
| 53 DCHECK(CalledOnValidThread()); | 53 DCHECK(CalledOnValidThread()); |
| 54 if (success) { | 54 if (success) { |
| 55 DCHECK(file_thread_message_loop_.get()); | 55 DCHECK(file_thread_task_runner_.get()); |
| 56 file_thread_message_loop_->PostTask( | 56 file_thread_task_runner_->PostTask( |
| 57 FROM_HERE, | 57 FROM_HERE, base::Bind(&SerialIoHandler::StartOpen, this, port, |
| 58 base::Bind(&SerialIoHandler::StartOpen, | 58 base::ThreadTaskRunnerHandle::Get())); |
| 59 this, | |
| 60 port, | |
| 61 base::MessageLoopProxy::current())); | |
| 62 return; | 59 return; |
| 63 } else { | 60 } else { |
| 64 DCHECK(!open_complete_.is_null()); | 61 DCHECK(!open_complete_.is_null()); |
| 65 OpenCompleteCallback callback = open_complete_; | 62 OpenCompleteCallback callback = open_complete_; |
| 66 open_complete_.Reset(); | 63 open_complete_.Reset(); |
| 67 callback.Run(false); | 64 callback.Run(false); |
| 68 return; | 65 return; |
| 69 } | 66 } |
| 70 } | 67 } |
| 71 | 68 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 84 options_.stop_bits = options.stop_bits; | 81 options_.stop_bits = options.stop_bits; |
| 85 } | 82 } |
| 86 if (options.has_cts_flow_control) { | 83 if (options.has_cts_flow_control) { |
| 87 DCHECK(options_.has_cts_flow_control); | 84 DCHECK(options_.has_cts_flow_control); |
| 88 options_.cts_flow_control = options.cts_flow_control; | 85 options_.cts_flow_control = options.cts_flow_control; |
| 89 } | 86 } |
| 90 } | 87 } |
| 91 | 88 |
| 92 void SerialIoHandler::StartOpen( | 89 void SerialIoHandler::StartOpen( |
| 93 const std::string& port, | 90 const std::string& port, |
| 94 scoped_refptr<base::MessageLoopProxy> io_message_loop) { | 91 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) { |
| 95 DCHECK(!open_complete_.is_null()); | 92 DCHECK(!open_complete_.is_null()); |
| 96 DCHECK(file_thread_message_loop_->RunsTasksOnCurrentThread()); | 93 DCHECK(file_thread_task_runner_->RunsTasksOnCurrentThread()); |
| 97 DCHECK(!file_.IsValid()); | 94 DCHECK(!file_.IsValid()); |
| 98 // It's the responsibility of the API wrapper around SerialIoHandler to | 95 // It's the responsibility of the API wrapper around SerialIoHandler to |
| 99 // validate the supplied path against the set of valid port names, and | 96 // validate the supplied path against the set of valid port names, and |
| 100 // it is a reasonable assumption that serial port names are ASCII. | 97 // it is a reasonable assumption that serial port names are ASCII. |
| 101 DCHECK(base::IsStringASCII(port)); | 98 DCHECK(base::IsStringASCII(port)); |
| 102 base::FilePath path(base::FilePath::FromUTF8Unsafe(MaybeFixUpPortName(port))); | 99 base::FilePath path(base::FilePath::FromUTF8Unsafe(MaybeFixUpPortName(port))); |
| 103 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ | | 100 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ | |
| 104 base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_WRITE | | 101 base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_WRITE | |
| 105 base::File::FLAG_EXCLUSIVE_WRITE | base::File::FLAG_ASYNC | | 102 base::File::FLAG_EXCLUSIVE_WRITE | base::File::FLAG_ASYNC | |
| 106 base::File::FLAG_TERMINAL_DEVICE; | 103 base::File::FLAG_TERMINAL_DEVICE; |
| 107 base::File file(path, flags); | 104 base::File file(path, flags); |
| 108 io_message_loop->PostTask( | 105 io_task_runner->PostTask(FROM_HERE, base::Bind(&SerialIoHandler::FinishOpen, |
| 109 FROM_HERE, | 106 this, Passed(file.Pass()))); |
| 110 base::Bind(&SerialIoHandler::FinishOpen, this, Passed(file.Pass()))); | |
| 111 } | 107 } |
| 112 | 108 |
| 113 void SerialIoHandler::FinishOpen(base::File file) { | 109 void SerialIoHandler::FinishOpen(base::File file) { |
| 114 DCHECK(CalledOnValidThread()); | 110 DCHECK(CalledOnValidThread()); |
| 115 DCHECK(!open_complete_.is_null()); | 111 DCHECK(!open_complete_.is_null()); |
| 116 OpenCompleteCallback callback = open_complete_; | 112 OpenCompleteCallback callback = open_complete_; |
| 117 open_complete_.Reset(); | 113 open_complete_.Reset(); |
| 118 | 114 |
| 119 if (!file.IsValid()) { | 115 if (!file.IsValid()) { |
| 120 LOG(ERROR) << "Failed to open serial port: " | 116 LOG(ERROR) << "Failed to open serial port: " |
| (...skipping 11 matching lines...) Expand all Loading... |
| 132 | 128 |
| 133 callback.Run(success); | 129 callback.Run(success); |
| 134 } | 130 } |
| 135 | 131 |
| 136 bool SerialIoHandler::PostOpen() { | 132 bool SerialIoHandler::PostOpen() { |
| 137 return true; | 133 return true; |
| 138 } | 134 } |
| 139 | 135 |
| 140 void SerialIoHandler::Close() { | 136 void SerialIoHandler::Close() { |
| 141 if (file_.IsValid()) { | 137 if (file_.IsValid()) { |
| 142 DCHECK(file_thread_message_loop_.get()); | 138 DCHECK(file_thread_task_runner_.get()); |
| 143 file_thread_message_loop_->PostTask( | 139 file_thread_task_runner_->PostTask( |
| 144 FROM_HERE, base::Bind(&SerialIoHandler::DoClose, Passed(file_.Pass()))); | 140 FROM_HERE, base::Bind(&SerialIoHandler::DoClose, Passed(file_.Pass()))); |
| 145 } | 141 } |
| 146 } | 142 } |
| 147 | 143 |
| 148 // static | 144 // static |
| 149 void SerialIoHandler::DoClose(base::File port) { | 145 void SerialIoHandler::DoClose(base::File port) { |
| 150 // port closed by destructor. | 146 // port closed by destructor. |
| 151 } | 147 } |
| 152 | 148 |
| 153 void SerialIoHandler::Read(scoped_ptr<WritableBuffer> buffer) { | 149 void SerialIoHandler::Read(scoped_ptr<WritableBuffer> buffer) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 } | 232 } |
| 237 | 233 |
| 238 void SerialIoHandler::QueueWriteCompleted(int bytes_written, | 234 void SerialIoHandler::QueueWriteCompleted(int bytes_written, |
| 239 serial::SendError error) { | 235 serial::SendError error) { |
| 240 base::MessageLoop::current()->PostTask( | 236 base::MessageLoop::current()->PostTask( |
| 241 FROM_HERE, | 237 FROM_HERE, |
| 242 base::Bind(&SerialIoHandler::WriteCompleted, this, bytes_written, error)); | 238 base::Bind(&SerialIoHandler::WriteCompleted, this, bytes_written, error)); |
| 243 } | 239 } |
| 244 | 240 |
| 245 } // namespace device | 241 } // namespace device |
| OLD | NEW |