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 |