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 "extensions/browser/api/serial/serial_connection.h" | 5 #include "extensions/browser/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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 case core_api::serial::STOP_BITS_NONE: | 126 case core_api::serial::STOP_BITS_NONE: |
127 return device::serial::STOP_BITS_NONE; | 127 return device::serial::STOP_BITS_NONE; |
128 case core_api::serial::STOP_BITS_ONE: | 128 case core_api::serial::STOP_BITS_ONE: |
129 return device::serial::STOP_BITS_ONE; | 129 return device::serial::STOP_BITS_ONE; |
130 case core_api::serial::STOP_BITS_TWO: | 130 case core_api::serial::STOP_BITS_TWO: |
131 return device::serial::STOP_BITS_TWO; | 131 return device::serial::STOP_BITS_TWO; |
132 } | 132 } |
133 return device::serial::STOP_BITS_NONE; | 133 return device::serial::STOP_BITS_NONE; |
134 } | 134 } |
135 | 135 |
| 136 class SendBuffer : public device::ReadOnlyBuffer { |
| 137 public: |
| 138 SendBuffer( |
| 139 const std::string& data, |
| 140 const base::Callback<void(int, device::serial::SendError)>& callback) |
| 141 : data_(data), callback_(callback) {} |
| 142 virtual ~SendBuffer() {} |
| 143 virtual const char* GetData() OVERRIDE { return data_.c_str(); } |
| 144 virtual uint32_t GetSize() OVERRIDE { |
| 145 return static_cast<uint32_t>(data_.size()); |
| 146 } |
| 147 virtual void Done(uint32_t bytes_read) OVERRIDE { |
| 148 callback_.Run(bytes_read, device::serial::SEND_ERROR_NONE); |
| 149 } |
| 150 virtual void DoneWithError(uint32_t bytes_read, int32_t error) OVERRIDE { |
| 151 callback_.Run(bytes_read, static_cast<device::serial::SendError>(error)); |
| 152 } |
| 153 |
| 154 private: |
| 155 const std::string data_; |
| 156 const base::Callback<void(int, device::serial::SendError)> callback_; |
| 157 }; |
| 158 |
| 159 class ReceiveBuffer : public device::WritableBuffer { |
| 160 public: |
| 161 ReceiveBuffer( |
| 162 scoped_refptr<net::IOBuffer> buffer, |
| 163 uint32_t size, |
| 164 const base::Callback<void(int, device::serial::ReceiveError)>& callback) |
| 165 : buffer_(buffer), size_(size), callback_(callback) {} |
| 166 virtual ~ReceiveBuffer() {} |
| 167 virtual char* GetData() OVERRIDE { return buffer_->data(); } |
| 168 virtual uint32_t GetSize() OVERRIDE { return size_; } |
| 169 virtual void Done(uint32_t bytes_written) OVERRIDE { |
| 170 callback_.Run(bytes_written, device::serial::RECEIVE_ERROR_NONE); |
| 171 } |
| 172 virtual void DoneWithError(uint32_t bytes_written, int32_t error) OVERRIDE { |
| 173 callback_.Run(bytes_written, |
| 174 static_cast<device::serial::ReceiveError>(error)); |
| 175 } |
| 176 |
| 177 private: |
| 178 scoped_refptr<net::IOBuffer> buffer_; |
| 179 const uint32_t size_; |
| 180 const base::Callback<void(int, device::serial::ReceiveError)> callback_; |
| 181 }; |
| 182 |
136 } // namespace | 183 } // namespace |
137 | 184 |
138 static base::LazyInstance< | 185 static base::LazyInstance< |
139 BrowserContextKeyedAPIFactory<ApiResourceManager<SerialConnection> > > | 186 BrowserContextKeyedAPIFactory<ApiResourceManager<SerialConnection> > > |
140 g_factory = LAZY_INSTANCE_INITIALIZER; | 187 g_factory = LAZY_INSTANCE_INITIALIZER; |
141 | 188 |
142 // static | 189 // static |
143 template <> | 190 template <> |
144 BrowserContextKeyedAPIFactory<ApiResourceManager<SerialConnection> >* | 191 BrowserContextKeyedAPIFactory<ApiResourceManager<SerialConnection> >* |
145 ApiResourceManager<SerialConnection>::GetFactoryInstance() { | 192 ApiResourceManager<SerialConnection>::GetFactoryInstance() { |
146 return g_factory.Pointer(); | 193 return g_factory.Pointer(); |
147 } | 194 } |
148 | 195 |
149 SerialConnection::SerialConnection(const std::string& port, | 196 SerialConnection::SerialConnection(const std::string& port, |
150 const std::string& owner_extension_id) | 197 const std::string& owner_extension_id) |
151 : ApiResource(owner_extension_id), | 198 : ApiResource(owner_extension_id), |
152 port_(port), | 199 port_(port), |
153 persistent_(false), | 200 persistent_(false), |
154 buffer_size_(kDefaultBufferSize), | 201 buffer_size_(kDefaultBufferSize), |
155 receive_timeout_(0), | 202 receive_timeout_(0), |
156 send_timeout_(0), | 203 send_timeout_(0), |
157 paused_(false), | 204 paused_(false), |
158 io_handler_(device::SerialIoHandler::Create( | 205 io_handler_(device::SerialIoHandler::Create( |
159 content::BrowserThread::GetMessageLoopProxyForThread( | 206 content::BrowserThread::GetMessageLoopProxyForThread( |
160 content::BrowserThread::FILE))) { | 207 content::BrowserThread::FILE))) { |
161 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 208 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
162 io_handler_->Initialize( | |
163 base::Bind(&SerialConnection::OnAsyncReadComplete, AsWeakPtr()), | |
164 base::Bind(&SerialConnection::OnAsyncWriteComplete, AsWeakPtr())); | |
165 } | 209 } |
166 | 210 |
167 SerialConnection::~SerialConnection() { | 211 SerialConnection::~SerialConnection() { |
168 io_handler_->CancelRead(device::serial::RECEIVE_ERROR_DISCONNECTED); | 212 io_handler_->CancelRead(device::serial::RECEIVE_ERROR_DISCONNECTED); |
169 io_handler_->CancelWrite(device::serial::SEND_ERROR_DISCONNECTED); | 213 io_handler_->CancelWrite(device::serial::SEND_ERROR_DISCONNECTED); |
170 } | 214 } |
171 | 215 |
172 bool SerialConnection::IsPersistent() const { | 216 bool SerialConnection::IsPersistent() const { |
173 return persistent(); | 217 return persistent(); |
174 } | 218 } |
(...skipping 20 matching lines...) Expand all Loading... |
195 void SerialConnection::Open(const OpenCompleteCallback& callback) { | 239 void SerialConnection::Open(const OpenCompleteCallback& callback) { |
196 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 240 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
197 io_handler_->Open(port_, callback); | 241 io_handler_->Open(port_, callback); |
198 } | 242 } |
199 | 243 |
200 bool SerialConnection::Receive(const ReceiveCompleteCallback& callback) { | 244 bool SerialConnection::Receive(const ReceiveCompleteCallback& callback) { |
201 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 245 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
202 if (!receive_complete_.is_null()) | 246 if (!receive_complete_.is_null()) |
203 return false; | 247 return false; |
204 receive_complete_ = callback; | 248 receive_complete_ = callback; |
205 io_handler_->Read(buffer_size_); | 249 receive_buffer_ = new net::IOBuffer(buffer_size_); |
| 250 io_handler_->Read(scoped_ptr<device::WritableBuffer>(new ReceiveBuffer( |
| 251 receive_buffer_, |
| 252 buffer_size_, |
| 253 base::Bind(&SerialConnection::OnAsyncReadComplete, AsWeakPtr())))); |
206 receive_timeout_task_.reset(); | 254 receive_timeout_task_.reset(); |
207 if (receive_timeout_ > 0) { | 255 if (receive_timeout_ > 0) { |
208 receive_timeout_task_.reset(new TimeoutTask( | 256 receive_timeout_task_.reset(new TimeoutTask( |
209 base::Bind(&SerialConnection::OnReceiveTimeout, AsWeakPtr()), | 257 base::Bind(&SerialConnection::OnReceiveTimeout, AsWeakPtr()), |
210 base::TimeDelta::FromMilliseconds(receive_timeout_))); | 258 base::TimeDelta::FromMilliseconds(receive_timeout_))); |
211 } | 259 } |
212 return true; | 260 return true; |
213 } | 261 } |
214 | 262 |
215 bool SerialConnection::Send(const std::string& data, | 263 bool SerialConnection::Send(const std::string& data, |
216 const SendCompleteCallback& callback) { | 264 const SendCompleteCallback& callback) { |
217 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 265 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
218 if (!send_complete_.is_null()) | 266 if (!send_complete_.is_null()) |
219 return false; | 267 return false; |
220 send_complete_ = callback; | 268 send_complete_ = callback; |
221 io_handler_->Write(data); | 269 io_handler_->Write(scoped_ptr<device::ReadOnlyBuffer>(new SendBuffer( |
| 270 data, base::Bind(&SerialConnection::OnAsyncWriteComplete, AsWeakPtr())))); |
222 send_timeout_task_.reset(); | 271 send_timeout_task_.reset(); |
223 if (send_timeout_ > 0) { | 272 if (send_timeout_ > 0) { |
224 send_timeout_task_.reset(new TimeoutTask( | 273 send_timeout_task_.reset(new TimeoutTask( |
225 base::Bind(&SerialConnection::OnSendTimeout, AsWeakPtr()), | 274 base::Bind(&SerialConnection::OnSendTimeout, AsWeakPtr()), |
226 base::TimeDelta::FromMilliseconds(send_timeout_))); | 275 base::TimeDelta::FromMilliseconds(send_timeout_))); |
227 } | 276 } |
228 return true; | 277 return true; |
229 } | 278 } |
230 | 279 |
231 bool SerialConnection::Configure( | 280 bool SerialConnection::Configure( |
(...skipping 11 matching lines...) Expand all Loading... |
243 set_send_timeout(*options.send_timeout); | 292 set_send_timeout(*options.send_timeout); |
244 bool success = io_handler_->ConfigurePort( | 293 bool success = io_handler_->ConfigurePort( |
245 *device::serial::ConnectionOptions::From(options)); | 294 *device::serial::ConnectionOptions::From(options)); |
246 io_handler_->CancelRead(device::serial::RECEIVE_ERROR_NONE); | 295 io_handler_->CancelRead(device::serial::RECEIVE_ERROR_NONE); |
247 return success; | 296 return success; |
248 } | 297 } |
249 | 298 |
250 void SerialConnection::SetIoHandlerForTest( | 299 void SerialConnection::SetIoHandlerForTest( |
251 scoped_refptr<device::SerialIoHandler> handler) { | 300 scoped_refptr<device::SerialIoHandler> handler) { |
252 io_handler_ = handler; | 301 io_handler_ = handler; |
253 io_handler_->Initialize( | |
254 base::Bind(&SerialConnection::OnAsyncReadComplete, AsWeakPtr()), | |
255 base::Bind(&SerialConnection::OnAsyncWriteComplete, AsWeakPtr())); | |
256 } | 302 } |
257 | 303 |
258 bool SerialConnection::GetInfo(core_api::serial::ConnectionInfo* info) const { | 304 bool SerialConnection::GetInfo(core_api::serial::ConnectionInfo* info) const { |
259 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 305 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
260 info->paused = paused_; | 306 info->paused = paused_; |
261 info->persistent = persistent_; | 307 info->persistent = persistent_; |
262 info->name = name_; | 308 info->name = name_; |
263 info->buffer_size = buffer_size_; | 309 info->buffer_size = buffer_size_; |
264 info->receive_timeout = receive_timeout_; | 310 info->receive_timeout = receive_timeout_; |
265 info->send_timeout = send_timeout_; | 311 info->send_timeout = send_timeout_; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 void SerialConnection::OnReceiveTimeout() { | 348 void SerialConnection::OnReceiveTimeout() { |
303 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 349 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
304 io_handler_->CancelRead(device::serial::RECEIVE_ERROR_TIMEOUT); | 350 io_handler_->CancelRead(device::serial::RECEIVE_ERROR_TIMEOUT); |
305 } | 351 } |
306 | 352 |
307 void SerialConnection::OnSendTimeout() { | 353 void SerialConnection::OnSendTimeout() { |
308 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 354 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
309 io_handler_->CancelWrite(device::serial::SEND_ERROR_TIMEOUT); | 355 io_handler_->CancelWrite(device::serial::SEND_ERROR_TIMEOUT); |
310 } | 356 } |
311 | 357 |
312 void SerialConnection::OnAsyncReadComplete(const std::string& data, | 358 void SerialConnection::OnAsyncReadComplete(int bytes_read, |
313 device::serial::ReceiveError error) { | 359 device::serial::ReceiveError error) { |
314 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 360 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
315 DCHECK(!receive_complete_.is_null()); | 361 DCHECK(!receive_complete_.is_null()); |
316 ReceiveCompleteCallback callback = receive_complete_; | 362 ReceiveCompleteCallback callback = receive_complete_; |
317 receive_complete_.Reset(); | 363 receive_complete_.Reset(); |
318 receive_timeout_task_.reset(); | 364 receive_timeout_task_.reset(); |
319 callback.Run(data, ConvertReceiveErrorFromMojo(error)); | 365 callback.Run(std::string(receive_buffer_->data(), bytes_read), |
| 366 ConvertReceiveErrorFromMojo(error)); |
| 367 receive_buffer_ = NULL; |
320 } | 368 } |
321 | 369 |
322 void SerialConnection::OnAsyncWriteComplete(int bytes_sent, | 370 void SerialConnection::OnAsyncWriteComplete(int bytes_sent, |
323 device::serial::SendError error) { | 371 device::serial::SendError error) { |
324 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 372 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
325 DCHECK(!send_complete_.is_null()); | 373 DCHECK(!send_complete_.is_null()); |
326 SendCompleteCallback callback = send_complete_; | 374 SendCompleteCallback callback = send_complete_; |
327 send_complete_.Reset(); | 375 send_complete_.Reset(); |
328 send_timeout_task_.reset(); | 376 send_timeout_task_.reset(); |
329 callback.Run(bytes_sent, ConvertSendErrorFromMojo(error)); | 377 callback.Run(bytes_sent, ConvertSendErrorFromMojo(error)); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 output->parity_bit = extensions::ConvertParityBitToMojo(input.parity_bit); | 428 output->parity_bit = extensions::ConvertParityBitToMojo(input.parity_bit); |
381 output->stop_bits = extensions::ConvertStopBitsToMojo(input.stop_bits); | 429 output->stop_bits = extensions::ConvertStopBitsToMojo(input.stop_bits); |
382 if (input.cts_flow_control.get()) { | 430 if (input.cts_flow_control.get()) { |
383 output->has_cts_flow_control = true; | 431 output->has_cts_flow_control = true; |
384 output->cts_flow_control = *input.cts_flow_control; | 432 output->cts_flow_control = *input.cts_flow_control; |
385 } | 433 } |
386 return output.Pass(); | 434 return output.Pass(); |
387 } | 435 } |
388 | 436 |
389 } // namespace mojo | 437 } // namespace mojo |
OLD | NEW |