Finish refactoring of DomCodeToUsLayoutKeyboardCode().
[chromium-blink-merge.git] / extensions / browser / api / serial / serial_connection.cc
blob16532b019c6c010edbafb68d9667d61799d3e61c
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 "extensions/browser/api/serial/serial_connection.h"
7 #include <string>
8 #include <vector>
10 #include "base/files/file_path.h"
11 #include "base/lazy_instance.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/stl_util.h"
14 #include "extensions/browser/api/api_resource_manager.h"
15 #include "extensions/common/api/serial.h"
17 namespace extensions {
19 namespace {
21 const int kDefaultBufferSize = 4096;
23 core_api::serial::SendError ConvertSendErrorFromMojo(
24 device::serial::SendError input) {
25 switch (input) {
26 case device::serial::SEND_ERROR_NONE:
27 return core_api::serial::SEND_ERROR_NONE;
28 case device::serial::SEND_ERROR_DISCONNECTED:
29 return core_api::serial::SEND_ERROR_DISCONNECTED;
30 case device::serial::SEND_ERROR_PENDING:
31 return core_api::serial::SEND_ERROR_PENDING;
32 case device::serial::SEND_ERROR_TIMEOUT:
33 return core_api::serial::SEND_ERROR_TIMEOUT;
34 case device::serial::SEND_ERROR_SYSTEM_ERROR:
35 return core_api::serial::SEND_ERROR_SYSTEM_ERROR;
37 return core_api::serial::SEND_ERROR_NONE;
40 core_api::serial::ReceiveError ConvertReceiveErrorFromMojo(
41 device::serial::ReceiveError input) {
42 switch (input) {
43 case device::serial::RECEIVE_ERROR_NONE:
44 return core_api::serial::RECEIVE_ERROR_NONE;
45 case device::serial::RECEIVE_ERROR_DISCONNECTED:
46 return core_api::serial::RECEIVE_ERROR_DISCONNECTED;
47 case device::serial::RECEIVE_ERROR_TIMEOUT:
48 return core_api::serial::RECEIVE_ERROR_TIMEOUT;
49 case device::serial::RECEIVE_ERROR_DEVICE_LOST:
50 return core_api::serial::RECEIVE_ERROR_DEVICE_LOST;
51 case device::serial::RECEIVE_ERROR_BREAK:
52 return core_api::serial::RECEIVE_ERROR_BREAK;
53 case device::serial::RECEIVE_ERROR_FRAME_ERROR:
54 return core_api::serial::RECEIVE_ERROR_FRAME_ERROR;
55 case device::serial::RECEIVE_ERROR_OVERRUN:
56 return core_api::serial::RECEIVE_ERROR_OVERRUN;
57 case device::serial::RECEIVE_ERROR_BUFFER_OVERFLOW:
58 return core_api::serial::RECEIVE_ERROR_BUFFER_OVERFLOW;
59 case device::serial::RECEIVE_ERROR_PARITY_ERROR:
60 return core_api::serial::RECEIVE_ERROR_PARITY_ERROR;
61 case device::serial::RECEIVE_ERROR_SYSTEM_ERROR:
62 return core_api::serial::RECEIVE_ERROR_SYSTEM_ERROR;
64 return core_api::serial::RECEIVE_ERROR_NONE;
67 core_api::serial::DataBits ConvertDataBitsFromMojo(
68 device::serial::DataBits input) {
69 switch (input) {
70 case device::serial::DATA_BITS_NONE:
71 return core_api::serial::DATA_BITS_NONE;
72 case device::serial::DATA_BITS_SEVEN:
73 return core_api::serial::DATA_BITS_SEVEN;
74 case device::serial::DATA_BITS_EIGHT:
75 return core_api::serial::DATA_BITS_EIGHT;
77 return core_api::serial::DATA_BITS_NONE;
80 device::serial::DataBits ConvertDataBitsToMojo(
81 core_api::serial::DataBits input) {
82 switch (input) {
83 case core_api::serial::DATA_BITS_NONE:
84 return device::serial::DATA_BITS_NONE;
85 case core_api::serial::DATA_BITS_SEVEN:
86 return device::serial::DATA_BITS_SEVEN;
87 case core_api::serial::DATA_BITS_EIGHT:
88 return device::serial::DATA_BITS_EIGHT;
90 return device::serial::DATA_BITS_NONE;
93 core_api::serial::ParityBit ConvertParityBitFromMojo(
94 device::serial::ParityBit input) {
95 switch (input) {
96 case device::serial::PARITY_BIT_NONE:
97 return core_api::serial::PARITY_BIT_NONE;
98 case device::serial::PARITY_BIT_ODD:
99 return core_api::serial::PARITY_BIT_ODD;
100 case device::serial::PARITY_BIT_NO:
101 return core_api::serial::PARITY_BIT_NO;
102 case device::serial::PARITY_BIT_EVEN:
103 return core_api::serial::PARITY_BIT_EVEN;
105 return core_api::serial::PARITY_BIT_NONE;
108 device::serial::ParityBit ConvertParityBitToMojo(
109 core_api::serial::ParityBit input) {
110 switch (input) {
111 case core_api::serial::PARITY_BIT_NONE:
112 return device::serial::PARITY_BIT_NONE;
113 case core_api::serial::PARITY_BIT_NO:
114 return device::serial::PARITY_BIT_NO;
115 case core_api::serial::PARITY_BIT_ODD:
116 return device::serial::PARITY_BIT_ODD;
117 case core_api::serial::PARITY_BIT_EVEN:
118 return device::serial::PARITY_BIT_EVEN;
120 return device::serial::PARITY_BIT_NONE;
123 core_api::serial::StopBits ConvertStopBitsFromMojo(
124 device::serial::StopBits input) {
125 switch (input) {
126 case device::serial::STOP_BITS_NONE:
127 return core_api::serial::STOP_BITS_NONE;
128 case device::serial::STOP_BITS_ONE:
129 return core_api::serial::STOP_BITS_ONE;
130 case device::serial::STOP_BITS_TWO:
131 return core_api::serial::STOP_BITS_TWO;
133 return core_api::serial::STOP_BITS_NONE;
136 device::serial::StopBits ConvertStopBitsToMojo(
137 core_api::serial::StopBits input) {
138 switch (input) {
139 case core_api::serial::STOP_BITS_NONE:
140 return device::serial::STOP_BITS_NONE;
141 case core_api::serial::STOP_BITS_ONE:
142 return device::serial::STOP_BITS_ONE;
143 case core_api::serial::STOP_BITS_TWO:
144 return device::serial::STOP_BITS_TWO;
146 return device::serial::STOP_BITS_NONE;
149 class SendBuffer : public device::ReadOnlyBuffer {
150 public:
151 SendBuffer(
152 const std::vector<char>& data,
153 const base::Callback<void(int, device::serial::SendError)>& callback)
154 : data_(data), callback_(callback) {}
155 ~SendBuffer() override {}
156 const char* GetData() override { return vector_as_array(&data_); }
157 uint32_t GetSize() override { return static_cast<uint32_t>(data_.size()); }
158 void Done(uint32_t bytes_read) override {
159 callback_.Run(bytes_read, device::serial::SEND_ERROR_NONE);
161 void DoneWithError(uint32_t bytes_read, int32_t error) override {
162 callback_.Run(bytes_read, static_cast<device::serial::SendError>(error));
165 private:
166 const std::vector<char> data_;
167 const base::Callback<void(int, device::serial::SendError)> callback_;
170 class ReceiveBuffer : public device::WritableBuffer {
171 public:
172 ReceiveBuffer(
173 scoped_refptr<net::IOBuffer> buffer,
174 uint32_t size,
175 const base::Callback<void(int, device::serial::ReceiveError)>& callback)
176 : buffer_(buffer), size_(size), callback_(callback) {}
177 ~ReceiveBuffer() override {}
178 char* GetData() override { return buffer_->data(); }
179 uint32_t GetSize() override { return size_; }
180 void Done(uint32_t bytes_written) override {
181 callback_.Run(bytes_written, device::serial::RECEIVE_ERROR_NONE);
183 void DoneWithError(uint32_t bytes_written, int32_t error) override {
184 callback_.Run(bytes_written,
185 static_cast<device::serial::ReceiveError>(error));
188 private:
189 scoped_refptr<net::IOBuffer> buffer_;
190 const uint32_t size_;
191 const base::Callback<void(int, device::serial::ReceiveError)> callback_;
194 } // namespace
196 static base::LazyInstance<
197 BrowserContextKeyedAPIFactory<ApiResourceManager<SerialConnection> > >
198 g_factory = LAZY_INSTANCE_INITIALIZER;
200 // static
201 template <>
202 BrowserContextKeyedAPIFactory<ApiResourceManager<SerialConnection> >*
203 ApiResourceManager<SerialConnection>::GetFactoryInstance() {
204 return g_factory.Pointer();
207 SerialConnection::SerialConnection(const std::string& port,
208 const std::string& owner_extension_id)
209 : ApiResource(owner_extension_id),
210 port_(port),
211 persistent_(false),
212 buffer_size_(kDefaultBufferSize),
213 receive_timeout_(0),
214 send_timeout_(0),
215 paused_(false),
216 io_handler_(device::SerialIoHandler::Create(
217 content::BrowserThread::GetMessageLoopProxyForThread(
218 content::BrowserThread::FILE),
219 content::BrowserThread::GetMessageLoopProxyForThread(
220 content::BrowserThread::UI))) {
221 DCHECK_CURRENTLY_ON(BrowserThread::IO);
224 SerialConnection::~SerialConnection() {
225 io_handler_->CancelRead(device::serial::RECEIVE_ERROR_DISCONNECTED);
226 io_handler_->CancelWrite(device::serial::SEND_ERROR_DISCONNECTED);
229 bool SerialConnection::IsPersistent() const {
230 return persistent();
233 void SerialConnection::set_buffer_size(int buffer_size) {
234 buffer_size_ = buffer_size;
237 void SerialConnection::set_receive_timeout(int receive_timeout) {
238 receive_timeout_ = receive_timeout;
241 void SerialConnection::set_send_timeout(int send_timeout) {
242 send_timeout_ = send_timeout;
245 void SerialConnection::set_paused(bool paused) {
246 paused_ = paused;
247 if (paused) {
248 io_handler_->CancelRead(device::serial::RECEIVE_ERROR_NONE);
252 void SerialConnection::Open(const core_api::serial::ConnectionOptions& options,
253 const OpenCompleteCallback& callback) {
254 DCHECK_CURRENTLY_ON(BrowserThread::IO);
255 if (options.persistent.get())
256 set_persistent(*options.persistent);
257 if (options.name.get())
258 set_name(*options.name);
259 if (options.buffer_size.get())
260 set_buffer_size(*options.buffer_size);
261 if (options.receive_timeout.get())
262 set_receive_timeout(*options.receive_timeout);
263 if (options.send_timeout.get())
264 set_send_timeout(*options.send_timeout);
265 io_handler_->Open(port_, *device::serial::ConnectionOptions::From(options),
266 callback);
269 bool SerialConnection::Receive(const ReceiveCompleteCallback& callback) {
270 DCHECK_CURRENTLY_ON(BrowserThread::IO);
271 if (!receive_complete_.is_null())
272 return false;
273 receive_complete_ = callback;
274 receive_buffer_ = new net::IOBuffer(buffer_size_);
275 io_handler_->Read(scoped_ptr<device::WritableBuffer>(new ReceiveBuffer(
276 receive_buffer_,
277 buffer_size_,
278 base::Bind(&SerialConnection::OnAsyncReadComplete, AsWeakPtr()))));
279 receive_timeout_task_.reset();
280 if (receive_timeout_ > 0) {
281 receive_timeout_task_.reset(new TimeoutTask(
282 base::Bind(&SerialConnection::OnReceiveTimeout, AsWeakPtr()),
283 base::TimeDelta::FromMilliseconds(receive_timeout_)));
285 return true;
288 bool SerialConnection::Send(const std::vector<char>& data,
289 const SendCompleteCallback& callback) {
290 DCHECK_CURRENTLY_ON(BrowserThread::IO);
291 if (!send_complete_.is_null())
292 return false;
293 send_complete_ = callback;
294 io_handler_->Write(scoped_ptr<device::ReadOnlyBuffer>(new SendBuffer(
295 data, base::Bind(&SerialConnection::OnAsyncWriteComplete, AsWeakPtr()))));
296 send_timeout_task_.reset();
297 if (send_timeout_ > 0) {
298 send_timeout_task_.reset(new TimeoutTask(
299 base::Bind(&SerialConnection::OnSendTimeout, AsWeakPtr()),
300 base::TimeDelta::FromMilliseconds(send_timeout_)));
302 return true;
305 bool SerialConnection::Configure(
306 const core_api::serial::ConnectionOptions& options) {
307 DCHECK_CURRENTLY_ON(BrowserThread::IO);
308 if (options.persistent.get())
309 set_persistent(*options.persistent);
310 if (options.name.get())
311 set_name(*options.name);
312 if (options.buffer_size.get())
313 set_buffer_size(*options.buffer_size);
314 if (options.receive_timeout.get())
315 set_receive_timeout(*options.receive_timeout);
316 if (options.send_timeout.get())
317 set_send_timeout(*options.send_timeout);
318 bool success = io_handler_->ConfigurePort(
319 *device::serial::ConnectionOptions::From(options));
320 io_handler_->CancelRead(device::serial::RECEIVE_ERROR_NONE);
321 return success;
324 void SerialConnection::SetIoHandlerForTest(
325 scoped_refptr<device::SerialIoHandler> handler) {
326 io_handler_ = handler;
329 bool SerialConnection::GetInfo(core_api::serial::ConnectionInfo* info) const {
330 DCHECK_CURRENTLY_ON(BrowserThread::IO);
331 info->paused = paused_;
332 info->persistent = persistent_;
333 info->name = name_;
334 info->buffer_size = buffer_size_;
335 info->receive_timeout = receive_timeout_;
336 info->send_timeout = send_timeout_;
337 device::serial::ConnectionInfoPtr port_info = io_handler_->GetPortInfo();
338 if (!port_info)
339 return false;
341 info->bitrate.reset(new int(port_info->bitrate));
342 info->data_bits = ConvertDataBitsFromMojo(port_info->data_bits);
343 info->parity_bit = ConvertParityBitFromMojo(port_info->parity_bit);
344 info->stop_bits = ConvertStopBitsFromMojo(port_info->stop_bits);
345 info->cts_flow_control.reset(new bool(port_info->cts_flow_control));
346 return true;
349 bool SerialConnection::Flush() const {
350 return io_handler_->Flush();
353 bool SerialConnection::GetControlSignals(
354 core_api::serial::DeviceControlSignals* control_signals) const {
355 device::serial::DeviceControlSignalsPtr signals =
356 io_handler_->GetControlSignals();
357 if (!signals)
358 return false;
360 control_signals->dcd = signals->dcd;
361 control_signals->cts = signals->cts;
362 control_signals->ri = signals->ri;
363 control_signals->dsr = signals->dsr;
364 return true;
367 bool SerialConnection::SetControlSignals(
368 const core_api::serial::HostControlSignals& control_signals) {
369 return io_handler_->SetControlSignals(
370 *device::serial::HostControlSignals::From(control_signals));
373 bool SerialConnection::SetBreak() {
374 return io_handler_->SetBreak();
377 bool SerialConnection::ClearBreak() {
378 return io_handler_->ClearBreak();
381 void SerialConnection::OnReceiveTimeout() {
382 DCHECK_CURRENTLY_ON(BrowserThread::IO);
383 io_handler_->CancelRead(device::serial::RECEIVE_ERROR_TIMEOUT);
386 void SerialConnection::OnSendTimeout() {
387 DCHECK_CURRENTLY_ON(BrowserThread::IO);
388 io_handler_->CancelWrite(device::serial::SEND_ERROR_TIMEOUT);
391 void SerialConnection::OnAsyncReadComplete(int bytes_read,
392 device::serial::ReceiveError error) {
393 DCHECK_CURRENTLY_ON(BrowserThread::IO);
394 DCHECK(!receive_complete_.is_null());
395 ReceiveCompleteCallback callback = receive_complete_;
396 receive_complete_.Reset();
397 receive_timeout_task_.reset();
398 callback.Run(std::vector<char>(receive_buffer_->data(),
399 receive_buffer_->data() + bytes_read),
400 ConvertReceiveErrorFromMojo(error));
401 receive_buffer_ = NULL;
404 void SerialConnection::OnAsyncWriteComplete(int bytes_sent,
405 device::serial::SendError error) {
406 DCHECK_CURRENTLY_ON(BrowserThread::IO);
407 DCHECK(!send_complete_.is_null());
408 SendCompleteCallback callback = send_complete_;
409 send_complete_.Reset();
410 send_timeout_task_.reset();
411 callback.Run(bytes_sent, ConvertSendErrorFromMojo(error));
414 SerialConnection::TimeoutTask::TimeoutTask(const base::Closure& closure,
415 const base::TimeDelta& delay)
416 : closure_(closure), delay_(delay), weak_factory_(this) {
417 base::MessageLoop::current()->PostDelayedTask(
418 FROM_HERE,
419 base::Bind(&TimeoutTask::Run, weak_factory_.GetWeakPtr()),
420 delay_);
423 SerialConnection::TimeoutTask::~TimeoutTask() {
426 void SerialConnection::TimeoutTask::Run() const {
427 closure_.Run();
430 } // namespace extensions
432 namespace mojo {
434 // static
435 device::serial::HostControlSignalsPtr
436 TypeConverter<device::serial::HostControlSignalsPtr,
437 extensions::core_api::serial::HostControlSignals>::
438 Convert(const extensions::core_api::serial::HostControlSignals& input) {
439 device::serial::HostControlSignalsPtr output(
440 device::serial::HostControlSignals::New());
441 if (input.dtr.get()) {
442 output->has_dtr = true;
443 output->dtr = *input.dtr;
445 if (input.rts.get()) {
446 output->has_rts = true;
447 output->rts = *input.rts;
449 return output.Pass();
452 // static
453 device::serial::ConnectionOptionsPtr
454 TypeConverter<device::serial::ConnectionOptionsPtr,
455 extensions::core_api::serial::ConnectionOptions>::
456 Convert(const extensions::core_api::serial::ConnectionOptions& input) {
457 device::serial::ConnectionOptionsPtr output(
458 device::serial::ConnectionOptions::New());
459 if (input.bitrate.get() && *input.bitrate > 0)
460 output->bitrate = *input.bitrate;
461 output->data_bits = extensions::ConvertDataBitsToMojo(input.data_bits);
462 output->parity_bit = extensions::ConvertParityBitToMojo(input.parity_bit);
463 output->stop_bits = extensions::ConvertStopBitsToMojo(input.stop_bits);
464 if (input.cts_flow_control.get()) {
465 output->has_cts_flow_control = true;
466 output->cts_flow_control = *input.cts_flow_control;
468 return output.Pass();
471 } // namespace mojo