Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: chrome/browser/extensions/api/serial/serial_connection.cc

Issue 369893008: Move the serial API to extensions/. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add missing dependency from usb_service to chromeos Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/api/serial/serial_connection.h"
6
7 #include <string>
8
9 #include "base/files/file_path.h"
10 #include "base/lazy_instance.h"
11 #include "chrome/common/extensions/api/serial.h"
12 #include "extensions/browser/api/api_resource_manager.h"
13
14 namespace extensions {
15
16 namespace {
17
18 const int kDefaultBufferSize = 4096;
19
20 api::serial::SendError ConvertSendErrorFromMojo(
21 device::serial::SendError input) {
22 switch (input) {
23 case device::serial::SEND_ERROR_NONE:
24 return api::serial::SEND_ERROR_NONE;
25 case device::serial::SEND_ERROR_DISCONNECTED:
26 return api::serial::SEND_ERROR_DISCONNECTED;
27 case device::serial::SEND_ERROR_PENDING:
28 return api::serial::SEND_ERROR_PENDING;
29 case device::serial::SEND_ERROR_TIMEOUT:
30 return api::serial::SEND_ERROR_TIMEOUT;
31 case device::serial::SEND_ERROR_SYSTEM_ERROR:
32 return api::serial::SEND_ERROR_SYSTEM_ERROR;
33 }
34 return api::serial::SEND_ERROR_NONE;
35 }
36
37 api::serial::ReceiveError ConvertReceiveErrorFromMojo(
38 device::serial::ReceiveError input) {
39 switch (input) {
40 case device::serial::RECEIVE_ERROR_NONE:
41 return api::serial::RECEIVE_ERROR_NONE;
42 case device::serial::RECEIVE_ERROR_DISCONNECTED:
43 return api::serial::RECEIVE_ERROR_DISCONNECTED;
44 case device::serial::RECEIVE_ERROR_TIMEOUT:
45 return api::serial::RECEIVE_ERROR_TIMEOUT;
46 case device::serial::RECEIVE_ERROR_DEVICE_LOST:
47 return api::serial::RECEIVE_ERROR_DEVICE_LOST;
48 case device::serial::RECEIVE_ERROR_SYSTEM_ERROR:
49 return api::serial::RECEIVE_ERROR_SYSTEM_ERROR;
50 }
51 return api::serial::RECEIVE_ERROR_NONE;
52 }
53
54 api::serial::DataBits ConvertDataBitsFromMojo(device::serial::DataBits input) {
55 switch (input) {
56 case device::serial::DATA_BITS_NONE:
57 return api::serial::DATA_BITS_NONE;
58 case device::serial::DATA_BITS_SEVEN:
59 return api::serial::DATA_BITS_SEVEN;
60 case device::serial::DATA_BITS_EIGHT:
61 return api::serial::DATA_BITS_EIGHT;
62 }
63 return api::serial::DATA_BITS_NONE;
64 }
65
66 device::serial::DataBits ConvertDataBitsToMojo(api::serial::DataBits input) {
67 switch (input) {
68 case api::serial::DATA_BITS_NONE:
69 return device::serial::DATA_BITS_NONE;
70 case api::serial::DATA_BITS_SEVEN:
71 return device::serial::DATA_BITS_SEVEN;
72 case api::serial::DATA_BITS_EIGHT:
73 return device::serial::DATA_BITS_EIGHT;
74 }
75 return device::serial::DATA_BITS_NONE;
76 }
77
78 api::serial::ParityBit ConvertParityBitFromMojo(
79 device::serial::ParityBit input) {
80 switch (input) {
81 case device::serial::PARITY_BIT_NONE:
82 return api::serial::PARITY_BIT_NONE;
83 case device::serial::PARITY_BIT_ODD:
84 return api::serial::PARITY_BIT_ODD;
85 case device::serial::PARITY_BIT_NO:
86 return api::serial::PARITY_BIT_NO;
87 case device::serial::PARITY_BIT_EVEN:
88 return api::serial::PARITY_BIT_EVEN;
89 }
90 return api::serial::PARITY_BIT_NONE;
91 }
92
93 device::serial::ParityBit ConvertParityBitToMojo(api::serial::ParityBit input) {
94 switch (input) {
95 case api::serial::PARITY_BIT_NONE:
96 return device::serial::PARITY_BIT_NONE;
97 case api::serial::PARITY_BIT_NO:
98 return device::serial::PARITY_BIT_NO;
99 case api::serial::PARITY_BIT_ODD:
100 return device::serial::PARITY_BIT_ODD;
101 case api::serial::PARITY_BIT_EVEN:
102 return device::serial::PARITY_BIT_EVEN;
103 }
104 return device::serial::PARITY_BIT_NONE;
105 }
106
107 api::serial::StopBits ConvertStopBitsFromMojo(device::serial::StopBits input) {
108 switch (input) {
109 case device::serial::STOP_BITS_NONE:
110 return api::serial::STOP_BITS_NONE;
111 case device::serial::STOP_BITS_ONE:
112 return api::serial::STOP_BITS_ONE;
113 case device::serial::STOP_BITS_TWO:
114 return api::serial::STOP_BITS_TWO;
115 }
116 return api::serial::STOP_BITS_NONE;
117 }
118
119 device::serial::StopBits ConvertStopBitsToMojo(api::serial::StopBits input) {
120 switch (input) {
121 case api::serial::STOP_BITS_NONE:
122 return device::serial::STOP_BITS_NONE;
123 case api::serial::STOP_BITS_ONE:
124 return device::serial::STOP_BITS_ONE;
125 case api::serial::STOP_BITS_TWO:
126 return device::serial::STOP_BITS_TWO;
127 }
128 return device::serial::STOP_BITS_NONE;
129 }
130
131 } // namespace
132
133 static base::LazyInstance<
134 BrowserContextKeyedAPIFactory<ApiResourceManager<SerialConnection> > >
135 g_factory = LAZY_INSTANCE_INITIALIZER;
136
137 // static
138 template <>
139 BrowserContextKeyedAPIFactory<ApiResourceManager<SerialConnection> >*
140 ApiResourceManager<SerialConnection>::GetFactoryInstance() {
141 return g_factory.Pointer();
142 }
143
144 SerialConnection::SerialConnection(const std::string& port,
145 const std::string& owner_extension_id)
146 : ApiResource(owner_extension_id),
147 port_(port),
148 persistent_(false),
149 buffer_size_(kDefaultBufferSize),
150 receive_timeout_(0),
151 send_timeout_(0),
152 paused_(false),
153 io_handler_(device::SerialIoHandler::Create()) {
154 DCHECK_CURRENTLY_ON(BrowserThread::IO);
155 io_handler_->Initialize(
156 base::Bind(&SerialConnection::OnAsyncReadComplete, AsWeakPtr()),
157 base::Bind(&SerialConnection::OnAsyncWriteComplete, AsWeakPtr()),
158 content::BrowserThread::GetMessageLoopProxyForThread(
159 content::BrowserThread::FILE));
160 }
161
162 SerialConnection::~SerialConnection() {
163 io_handler_->CancelRead(device::serial::RECEIVE_ERROR_DISCONNECTED);
164 io_handler_->CancelWrite(device::serial::SEND_ERROR_DISCONNECTED);
165 }
166
167 bool SerialConnection::IsPersistent() const { return persistent(); }
168
169 void SerialConnection::set_buffer_size(int buffer_size) {
170 buffer_size_ = buffer_size;
171 }
172
173 void SerialConnection::set_receive_timeout(int receive_timeout) {
174 receive_timeout_ = receive_timeout;
175 }
176
177 void SerialConnection::set_send_timeout(int send_timeout) {
178 send_timeout_ = send_timeout;
179 }
180
181 void SerialConnection::set_paused(bool paused) {
182 paused_ = paused;
183 if (paused) {
184 io_handler_->CancelRead(device::serial::RECEIVE_ERROR_NONE);
185 }
186 }
187
188 void SerialConnection::Open(const OpenCompleteCallback& callback) {
189 DCHECK_CURRENTLY_ON(BrowserThread::IO);
190 io_handler_->Open(port_, callback);
191 }
192
193 bool SerialConnection::Receive(const ReceiveCompleteCallback& callback) {
194 DCHECK_CURRENTLY_ON(BrowserThread::IO);
195 if (!receive_complete_.is_null())
196 return false;
197 receive_complete_ = callback;
198 io_handler_->Read(buffer_size_);
199 receive_timeout_task_.reset();
200 if (receive_timeout_ > 0) {
201 receive_timeout_task_.reset(new TimeoutTask(
202 base::Bind(&SerialConnection::OnReceiveTimeout, AsWeakPtr()),
203 base::TimeDelta::FromMilliseconds(receive_timeout_)));
204 }
205 return true;
206 }
207
208 bool SerialConnection::Send(const std::string& data,
209 const SendCompleteCallback& callback) {
210 DCHECK_CURRENTLY_ON(BrowserThread::IO);
211 if (!send_complete_.is_null())
212 return false;
213 send_complete_ = callback;
214 io_handler_->Write(data);
215 send_timeout_task_.reset();
216 if (send_timeout_ > 0) {
217 send_timeout_task_.reset(new TimeoutTask(
218 base::Bind(&SerialConnection::OnSendTimeout, AsWeakPtr()),
219 base::TimeDelta::FromMilliseconds(send_timeout_)));
220 }
221 return true;
222 }
223
224 bool SerialConnection::Configure(
225 const api::serial::ConnectionOptions& options) {
226 DCHECK_CURRENTLY_ON(BrowserThread::IO);
227 if (options.persistent.get())
228 set_persistent(*options.persistent);
229 if (options.name.get())
230 set_name(*options.name);
231 if (options.buffer_size.get())
232 set_buffer_size(*options.buffer_size);
233 if (options.receive_timeout.get())
234 set_receive_timeout(*options.receive_timeout);
235 if (options.send_timeout.get())
236 set_send_timeout(*options.send_timeout);
237 bool success = io_handler_->ConfigurePort(
238 *device::serial::ConnectionOptions::From(options));
239 io_handler_->CancelRead(device::serial::RECEIVE_ERROR_NONE);
240 return success;
241 }
242
243 void SerialConnection::SetIoHandlerForTest(
244 scoped_refptr<device::SerialIoHandler> handler) {
245 io_handler_ = handler;
246 io_handler_->Initialize(
247 base::Bind(&SerialConnection::OnAsyncReadComplete, AsWeakPtr()),
248 base::Bind(&SerialConnection::OnAsyncWriteComplete, AsWeakPtr()),
249 content::BrowserThread::GetMessageLoopProxyForThread(
250 content::BrowserThread::FILE));
251 }
252
253 bool SerialConnection::GetInfo(api::serial::ConnectionInfo* info) const {
254 DCHECK_CURRENTLY_ON(BrowserThread::IO);
255 info->paused = paused_;
256 info->persistent = persistent_;
257 info->name = name_;
258 info->buffer_size = buffer_size_;
259 info->receive_timeout = receive_timeout_;
260 info->send_timeout = send_timeout_;
261 device::serial::ConnectionInfoPtr port_info = io_handler_->GetPortInfo();
262 if (!port_info)
263 return false;
264
265 info->bitrate.reset(new int(port_info->bitrate));
266 info->data_bits = ConvertDataBitsFromMojo(port_info->data_bits);
267 info->parity_bit = ConvertParityBitFromMojo(port_info->parity_bit);
268 info->stop_bits = ConvertStopBitsFromMojo(port_info->stop_bits);
269 info->cts_flow_control.reset(new bool(port_info->cts_flow_control));
270 return true;
271 }
272
273 bool SerialConnection::Flush() const {
274 return io_handler_->Flush();
275 }
276
277 bool SerialConnection::GetControlSignals(
278 api::serial::DeviceControlSignals* control_signals) const {
279 device::serial::DeviceControlSignalsPtr signals =
280 io_handler_->GetControlSignals();
281 if (!signals)
282 return false;
283
284 control_signals->dcd = signals->dcd;
285 control_signals->cts = signals->cts;
286 control_signals->ri = signals->ri;
287 control_signals->dsr = signals->dsr;
288 return true;
289 }
290
291 bool SerialConnection::SetControlSignals(
292 const api::serial::HostControlSignals& control_signals) {
293 return io_handler_->SetControlSignals(
294 *device::serial::HostControlSignals::From(control_signals));
295 }
296
297 void SerialConnection::OnReceiveTimeout() {
298 DCHECK_CURRENTLY_ON(BrowserThread::IO);
299 io_handler_->CancelRead(device::serial::RECEIVE_ERROR_TIMEOUT);
300 }
301
302 void SerialConnection::OnSendTimeout() {
303 DCHECK_CURRENTLY_ON(BrowserThread::IO);
304 io_handler_->CancelWrite(device::serial::SEND_ERROR_TIMEOUT);
305 }
306
307 void SerialConnection::OnAsyncReadComplete(const std::string& data,
308 device::serial::ReceiveError error) {
309 DCHECK_CURRENTLY_ON(BrowserThread::IO);
310 DCHECK(!receive_complete_.is_null());
311 ReceiveCompleteCallback callback = receive_complete_;
312 receive_complete_.Reset();
313 receive_timeout_task_.reset();
314 callback.Run(data, ConvertReceiveErrorFromMojo(error));
315 }
316
317 void SerialConnection::OnAsyncWriteComplete(int bytes_sent,
318 device::serial::SendError error) {
319 DCHECK_CURRENTLY_ON(BrowserThread::IO);
320 DCHECK(!send_complete_.is_null());
321 SendCompleteCallback callback = send_complete_;
322 send_complete_.Reset();
323 send_timeout_task_.reset();
324 callback.Run(bytes_sent, ConvertSendErrorFromMojo(error));
325 }
326
327 SerialConnection::TimeoutTask::TimeoutTask(const base::Closure& closure,
328 const base::TimeDelta& delay)
329 : weak_factory_(this), closure_(closure), delay_(delay) {
330 base::MessageLoop::current()->PostDelayedTask(
331 FROM_HERE,
332 base::Bind(&TimeoutTask::Run, weak_factory_.GetWeakPtr()),
333 delay_);
334 }
335
336 SerialConnection::TimeoutTask::~TimeoutTask() {}
337
338 void SerialConnection::TimeoutTask::Run() const { closure_.Run(); }
339
340 } // namespace extensions
341
342 namespace mojo {
343
344 // static
345 device::serial::HostControlSignalsPtr
346 TypeConverter<device::serial::HostControlSignalsPtr,
347 extensions::api::serial::HostControlSignals>::
348 ConvertFrom(const extensions::api::serial::HostControlSignals& input) {
349 device::serial::HostControlSignalsPtr output(
350 device::serial::HostControlSignals::New());
351 if (input.dtr.get()) {
352 output->has_dtr = true;
353 output->dtr = *input.dtr;
354 }
355 if (input.rts.get()) {
356 output->has_rts = true;
357 output->rts = *input.rts;
358 }
359 return output.Pass();
360 }
361
362 // static
363 device::serial::ConnectionOptionsPtr
364 TypeConverter<device::serial::ConnectionOptionsPtr,
365 extensions::api::serial::ConnectionOptions>::
366 ConvertFrom(const extensions::api::serial::ConnectionOptions& input) {
367 device::serial::ConnectionOptionsPtr output(
368 device::serial::ConnectionOptions::New());
369 if (input.bitrate.get() && *input.bitrate > 0)
370 output->bitrate = *input.bitrate;
371 output->data_bits = extensions::ConvertDataBitsToMojo(input.data_bits);
372 output->parity_bit = extensions::ConvertParityBitToMojo(input.parity_bit);
373 output->stop_bits = extensions::ConvertStopBitsToMojo(input.stop_bits);
374 if (input.cts_flow_control.get()) {
375 output->has_cts_flow_control = true;
376 output->cts_flow_control = *input.cts_flow_control;
377 }
378 return output.Pass();
379 }
380
381 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698