OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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 "chrome/browser/extensions/api/serial/serial_connection.h" | 5 #include "chrome/browser/extensions/api/serial/serial_connection.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 SerialConnection::SerialConnection(const std::string& port, | 33 SerialConnection::SerialConnection(const std::string& port, |
34 const std::string& owner_extension_id) | 34 const std::string& owner_extension_id) |
35 : ApiResource(owner_extension_id), | 35 : ApiResource(owner_extension_id), |
36 port_(port), | 36 port_(port), |
37 persistent_(false), | 37 persistent_(false), |
38 buffer_size_(kDefaultBufferSize), | 38 buffer_size_(kDefaultBufferSize), |
39 receive_timeout_(0), | 39 receive_timeout_(0), |
40 send_timeout_(0), | 40 send_timeout_(0), |
41 paused_(false), | 41 paused_(false), |
42 io_handler_(SerialIoHandler::Create()) { | 42 io_handler_(SerialIoHandler::Create()) { |
43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 43 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
44 } | 44 } |
45 | 45 |
46 SerialConnection::~SerialConnection() { | 46 SerialConnection::~SerialConnection() { |
47 DCHECK(open_complete_.is_null()); | 47 DCHECK(open_complete_.is_null()); |
48 io_handler_->CancelRead(api::serial::RECEIVE_ERROR_DISCONNECTED); | 48 io_handler_->CancelRead(api::serial::RECEIVE_ERROR_DISCONNECTED); |
49 io_handler_->CancelWrite(api::serial::SEND_ERROR_DISCONNECTED); | 49 io_handler_->CancelWrite(api::serial::SEND_ERROR_DISCONNECTED); |
50 Close(); | 50 Close(); |
51 } | 51 } |
52 | 52 |
53 bool SerialConnection::IsPersistent() const { return persistent(); } | 53 bool SerialConnection::IsPersistent() const { return persistent(); } |
(...skipping 11 matching lines...) Expand all Loading... |
65 } | 65 } |
66 | 66 |
67 void SerialConnection::set_paused(bool paused) { | 67 void SerialConnection::set_paused(bool paused) { |
68 paused_ = paused; | 68 paused_ = paused; |
69 if (paused) { | 69 if (paused) { |
70 io_handler_->CancelRead(api::serial::RECEIVE_ERROR_NONE); | 70 io_handler_->CancelRead(api::serial::RECEIVE_ERROR_NONE); |
71 } | 71 } |
72 } | 72 } |
73 | 73 |
74 void SerialConnection::Open(const OpenCompleteCallback& callback) { | 74 void SerialConnection::Open(const OpenCompleteCallback& callback) { |
75 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 75 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
76 DCHECK(open_complete_.is_null()); | 76 DCHECK(open_complete_.is_null()); |
77 open_complete_ = callback; | 77 open_complete_ = callback; |
78 BrowserThread::PostTask( | 78 BrowserThread::PostTask( |
79 BrowserThread::FILE, | 79 BrowserThread::FILE, |
80 FROM_HERE, | 80 FROM_HERE, |
81 base::Bind(&SerialConnection::StartOpen, base::Unretained(this))); | 81 base::Bind(&SerialConnection::StartOpen, base::Unretained(this))); |
82 } | 82 } |
83 | 83 |
84 void SerialConnection::Close() { | 84 void SerialConnection::Close() { |
85 DCHECK(open_complete_.is_null()); | 85 DCHECK(open_complete_.is_null()); |
86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 86 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
87 if (file_.IsValid()) { | 87 if (file_.IsValid()) { |
88 BrowserThread::PostTask( | 88 BrowserThread::PostTask( |
89 BrowserThread::FILE, | 89 BrowserThread::FILE, |
90 FROM_HERE, | 90 FROM_HERE, |
91 base::Bind(&SerialConnection::DoClose, Passed(file_.Pass()))); | 91 base::Bind(&SerialConnection::DoClose, Passed(file_.Pass()))); |
92 } | 92 } |
93 } | 93 } |
94 | 94 |
95 bool SerialConnection::Receive(const ReceiveCompleteCallback& callback) { | 95 bool SerialConnection::Receive(const ReceiveCompleteCallback& callback) { |
96 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 96 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
97 if (!receive_complete_.is_null()) | 97 if (!receive_complete_.is_null()) |
98 return false; | 98 return false; |
99 receive_complete_ = callback; | 99 receive_complete_ = callback; |
100 io_handler_->Read(buffer_size_); | 100 io_handler_->Read(buffer_size_); |
101 receive_timeout_task_.reset(); | 101 receive_timeout_task_.reset(); |
102 if (receive_timeout_ > 0) { | 102 if (receive_timeout_ > 0) { |
103 receive_timeout_task_.reset(new TimeoutTask( | 103 receive_timeout_task_.reset(new TimeoutTask( |
104 base::Bind(&SerialConnection::OnReceiveTimeout, AsWeakPtr()), | 104 base::Bind(&SerialConnection::OnReceiveTimeout, AsWeakPtr()), |
105 base::TimeDelta::FromMilliseconds(receive_timeout_))); | 105 base::TimeDelta::FromMilliseconds(receive_timeout_))); |
106 } | 106 } |
107 return true; | 107 return true; |
108 } | 108 } |
109 | 109 |
110 bool SerialConnection::Send(const std::string& data, | 110 bool SerialConnection::Send(const std::string& data, |
111 const SendCompleteCallback& callback) { | 111 const SendCompleteCallback& callback) { |
112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 112 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
113 if (!send_complete_.is_null()) | 113 if (!send_complete_.is_null()) |
114 return false; | 114 return false; |
115 send_complete_ = callback; | 115 send_complete_ = callback; |
116 io_handler_->Write(data); | 116 io_handler_->Write(data); |
117 send_timeout_task_.reset(); | 117 send_timeout_task_.reset(); |
118 if (send_timeout_ > 0) { | 118 if (send_timeout_ > 0) { |
119 send_timeout_task_.reset(new TimeoutTask( | 119 send_timeout_task_.reset(new TimeoutTask( |
120 base::Bind(&SerialConnection::OnSendTimeout, AsWeakPtr()), | 120 base::Bind(&SerialConnection::OnSendTimeout, AsWeakPtr()), |
121 base::TimeDelta::FromMilliseconds(send_timeout_))); | 121 base::TimeDelta::FromMilliseconds(send_timeout_))); |
122 } | 122 } |
123 return true; | 123 return true; |
124 } | 124 } |
125 | 125 |
126 bool SerialConnection::Configure( | 126 bool SerialConnection::Configure( |
127 const api::serial::ConnectionOptions& options) { | 127 const api::serial::ConnectionOptions& options) { |
128 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 128 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
129 if (options.persistent.get()) | 129 if (options.persistent.get()) |
130 set_persistent(*options.persistent); | 130 set_persistent(*options.persistent); |
131 if (options.name.get()) | 131 if (options.name.get()) |
132 set_name(*options.name); | 132 set_name(*options.name); |
133 if (options.buffer_size.get()) | 133 if (options.buffer_size.get()) |
134 set_buffer_size(*options.buffer_size); | 134 set_buffer_size(*options.buffer_size); |
135 if (options.receive_timeout.get()) | 135 if (options.receive_timeout.get()) |
136 set_receive_timeout(*options.receive_timeout); | 136 set_receive_timeout(*options.receive_timeout); |
137 if (options.send_timeout.get()) | 137 if (options.send_timeout.get()) |
138 set_send_timeout(*options.send_timeout); | 138 set_send_timeout(*options.send_timeout); |
139 bool success = ConfigurePort(options); | 139 bool success = ConfigurePort(options); |
140 io_handler_->CancelRead(api::serial::RECEIVE_ERROR_NONE); | 140 io_handler_->CancelRead(api::serial::RECEIVE_ERROR_NONE); |
141 return success; | 141 return success; |
142 } | 142 } |
143 | 143 |
144 void SerialConnection::SetIoHandlerForTest( | 144 void SerialConnection::SetIoHandlerForTest( |
145 scoped_refptr<SerialIoHandler> handler) { | 145 scoped_refptr<SerialIoHandler> handler) { |
146 io_handler_ = handler; | 146 io_handler_ = handler; |
147 } | 147 } |
148 | 148 |
149 bool SerialConnection::GetInfo(api::serial::ConnectionInfo* info) const { | 149 bool SerialConnection::GetInfo(api::serial::ConnectionInfo* info) const { |
150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 150 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
151 info->paused = paused_; | 151 info->paused = paused_; |
152 info->persistent = persistent_; | 152 info->persistent = persistent_; |
153 info->name = name_; | 153 info->name = name_; |
154 info->buffer_size = buffer_size_; | 154 info->buffer_size = buffer_size_; |
155 info->receive_timeout = receive_timeout_; | 155 info->receive_timeout = receive_timeout_; |
156 info->send_timeout = send_timeout_; | 156 info->send_timeout = send_timeout_; |
157 return GetPortInfo(info); | 157 return GetPortInfo(info); |
158 } | 158 } |
159 | 159 |
160 void SerialConnection::StartOpen() { | 160 void SerialConnection::StartOpen() { |
161 DCHECK(!open_complete_.is_null()); | 161 DCHECK(!open_complete_.is_null()); |
162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 162 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
163 DCHECK(!file_.IsValid()); | 163 DCHECK(!file_.IsValid()); |
164 // It's the responsibility of the API wrapper around SerialConnection to | 164 // It's the responsibility of the API wrapper around SerialConnection to |
165 // validate the supplied path against the set of valid port names, and | 165 // validate the supplied path against the set of valid port names, and |
166 // it is a reasonable assumption that serial port names are ASCII. | 166 // it is a reasonable assumption that serial port names are ASCII. |
167 DCHECK(IsStringASCII(port_)); | 167 DCHECK(IsStringASCII(port_)); |
168 base::FilePath path( | 168 base::FilePath path( |
169 base::FilePath::FromUTF8Unsafe(MaybeFixUpPortName(port_))); | 169 base::FilePath::FromUTF8Unsafe(MaybeFixUpPortName(port_))); |
170 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ | | 170 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ | |
171 base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_WRITE | | 171 base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_WRITE | |
172 base::File::FLAG_EXCLUSIVE_WRITE | base::File::FLAG_ASYNC | | 172 base::File::FLAG_EXCLUSIVE_WRITE | base::File::FLAG_ASYNC | |
173 base::File::FLAG_TERMINAL_DEVICE; | 173 base::File::FLAG_TERMINAL_DEVICE; |
174 base::File file(path, flags); | 174 base::File file(path, flags); |
175 BrowserThread::PostTask( | 175 BrowserThread::PostTask( |
176 BrowserThread::IO, | 176 BrowserThread::IO, |
177 FROM_HERE, | 177 FROM_HERE, |
178 base::Bind(&SerialConnection::FinishOpen, base::Unretained(this), | 178 base::Bind(&SerialConnection::FinishOpen, base::Unretained(this), |
179 Passed(file.Pass()))); | 179 Passed(file.Pass()))); |
180 } | 180 } |
181 | 181 |
182 void SerialConnection::FinishOpen(base::File file) { | 182 void SerialConnection::FinishOpen(base::File file) { |
183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 183 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
184 DCHECK(!open_complete_.is_null()); | 184 DCHECK(!open_complete_.is_null()); |
185 DCHECK(!file_.IsValid()); | 185 DCHECK(!file_.IsValid()); |
186 OpenCompleteCallback callback = open_complete_; | 186 OpenCompleteCallback callback = open_complete_; |
187 open_complete_.Reset(); | 187 open_complete_.Reset(); |
188 | 188 |
189 if (!file.IsValid()) { | 189 if (!file.IsValid()) { |
190 callback.Run(false); | 190 callback.Run(false); |
191 return; | 191 return; |
192 } | 192 } |
193 | 193 |
194 // TODO(rvargas): crbug.com/351073. This is wrong. io_handler_ keeps a copy of | 194 // TODO(rvargas): crbug.com/351073. This is wrong. io_handler_ keeps a copy of |
195 // the handler that is not in sync with this one. | 195 // the handler that is not in sync with this one. |
196 file_ = file.Pass(); | 196 file_ = file.Pass(); |
197 io_handler_->Initialize( | 197 io_handler_->Initialize( |
198 file_.GetPlatformFile(), | 198 file_.GetPlatformFile(), |
199 base::Bind(&SerialConnection::OnAsyncReadComplete, AsWeakPtr()), | 199 base::Bind(&SerialConnection::OnAsyncReadComplete, AsWeakPtr()), |
200 base::Bind(&SerialConnection::OnAsyncWriteComplete, AsWeakPtr())); | 200 base::Bind(&SerialConnection::OnAsyncWriteComplete, AsWeakPtr())); |
201 | 201 |
202 bool success = PostOpen(); | 202 bool success = PostOpen(); |
203 if (!success) { | 203 if (!success) { |
204 Close(); | 204 Close(); |
205 } | 205 } |
206 | 206 |
207 callback.Run(success); | 207 callback.Run(success); |
208 } | 208 } |
209 | 209 |
210 // static | 210 // static |
211 void SerialConnection::DoClose(base::File port) { | 211 void SerialConnection::DoClose(base::File port) { |
212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 212 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
213 // port closed by destructor. | 213 // port closed by destructor. |
214 } | 214 } |
215 | 215 |
216 void SerialConnection::OnReceiveTimeout() { | 216 void SerialConnection::OnReceiveTimeout() { |
217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 217 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
218 io_handler_->CancelRead(api::serial::RECEIVE_ERROR_TIMEOUT); | 218 io_handler_->CancelRead(api::serial::RECEIVE_ERROR_TIMEOUT); |
219 } | 219 } |
220 | 220 |
221 void SerialConnection::OnSendTimeout() { | 221 void SerialConnection::OnSendTimeout() { |
222 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 222 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
223 io_handler_->CancelWrite(api::serial::SEND_ERROR_TIMEOUT); | 223 io_handler_->CancelWrite(api::serial::SEND_ERROR_TIMEOUT); |
224 } | 224 } |
225 | 225 |
226 void SerialConnection::OnAsyncReadComplete(const std::string& data, | 226 void SerialConnection::OnAsyncReadComplete(const std::string& data, |
227 api::serial::ReceiveError error) { | 227 api::serial::ReceiveError error) { |
228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 228 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
229 DCHECK(!receive_complete_.is_null()); | 229 DCHECK(!receive_complete_.is_null()); |
230 ReceiveCompleteCallback callback = receive_complete_; | 230 ReceiveCompleteCallback callback = receive_complete_; |
231 receive_complete_.Reset(); | 231 receive_complete_.Reset(); |
232 receive_timeout_task_.reset(); | 232 receive_timeout_task_.reset(); |
233 callback.Run(data, error); | 233 callback.Run(data, error); |
234 } | 234 } |
235 | 235 |
236 void SerialConnection::OnAsyncWriteComplete(int bytes_sent, | 236 void SerialConnection::OnAsyncWriteComplete(int bytes_sent, |
237 api::serial::SendError error) { | 237 api::serial::SendError error) { |
238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 238 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
239 DCHECK(!send_complete_.is_null()); | 239 DCHECK(!send_complete_.is_null()); |
240 SendCompleteCallback callback = send_complete_; | 240 SendCompleteCallback callback = send_complete_; |
241 send_complete_.Reset(); | 241 send_complete_.Reset(); |
242 send_timeout_task_.reset(); | 242 send_timeout_task_.reset(); |
243 callback.Run(bytes_sent, error); | 243 callback.Run(bytes_sent, error); |
244 } | 244 } |
245 | 245 |
246 SerialConnection::TimeoutTask::TimeoutTask(const base::Closure& closure, | 246 SerialConnection::TimeoutTask::TimeoutTask(const base::Closure& closure, |
247 const base::TimeDelta& delay) | 247 const base::TimeDelta& delay) |
248 : weak_factory_(this), closure_(closure), delay_(delay) { | 248 : weak_factory_(this), closure_(closure), delay_(delay) { |
249 base::MessageLoop::current()->PostDelayedTask( | 249 base::MessageLoop::current()->PostDelayedTask( |
250 FROM_HERE, | 250 FROM_HERE, |
251 base::Bind(&TimeoutTask::Run, weak_factory_.GetWeakPtr()), | 251 base::Bind(&TimeoutTask::Run, weak_factory_.GetWeakPtr()), |
252 delay_); | 252 delay_); |
253 } | 253 } |
254 | 254 |
255 SerialConnection::TimeoutTask::~TimeoutTask() {} | 255 SerialConnection::TimeoutTask::~TimeoutTask() {} |
256 | 256 |
257 void SerialConnection::TimeoutTask::Run() const { closure_.Run(); } | 257 void SerialConnection::TimeoutTask::Run() const { closure_.Run(); } |
258 | 258 |
259 } // namespace extensions | 259 } // namespace extensions |
OLD | NEW |