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

Side by Side Diff: chrome/browser/extensions/api/serial/serial_api.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_api.h"
6
7 #include <algorithm>
8
9 #include "base/values.h"
10 #include "chrome/browser/extensions/api/serial/serial_connection.h"
11 #include "chrome/browser/extensions/api/serial/serial_event_dispatcher.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/common/extensions/api/serial.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "device/serial/serial_device_enumerator.h"
16 #include "extensions/browser/extension_system.h"
17
18 using content::BrowserThread;
19
20 namespace extensions {
21
22 namespace api {
23
24 namespace {
25
26 // It's a fool's errand to come up with a default bitrate, because we don't get
27 // to control both sides of the communication. Unless the other side has
28 // implemented auto-bitrate detection (rare), if we pick the wrong rate, then
29 // you're gonna have a bad time. Close doesn't count.
30 //
31 // But we'd like to pick something that has a chance of working, and 9600 is a
32 // good balance between popularity and speed. So 9600 it is.
33 const int kDefaultBufferSize = 4096;
34 const int kDefaultBitrate = 9600;
35 const serial::DataBits kDefaultDataBits = serial::DATA_BITS_EIGHT;
36 const serial::ParityBit kDefaultParityBit = serial::PARITY_BIT_NO;
37 const serial::StopBits kDefaultStopBits = serial::STOP_BITS_ONE;
38 const int kDefaultReceiveTimeout = 0;
39 const int kDefaultSendTimeout = 0;
40
41 const char kErrorConnectFailed[] = "Failed to connect to the port.";
42 const char kErrorSerialConnectionNotFound[] = "Serial connection not found.";
43 const char kErrorGetControlSignalsFailed[] = "Failed to get control signals.";
44
45 template <class T>
46 void SetDefaultScopedPtrValue(scoped_ptr<T>& ptr, const T& value) {
47 if (!ptr.get())
48 ptr.reset(new T(value));
49 }
50
51 } // namespace
52
53 SerialAsyncApiFunction::SerialAsyncApiFunction()
54 : manager_(NULL) {
55 }
56
57 SerialAsyncApiFunction::~SerialAsyncApiFunction() {}
58
59 bool SerialAsyncApiFunction::PrePrepare() {
60 manager_ = ApiResourceManager<SerialConnection>::Get(browser_context());
61 DCHECK(manager_);
62 return true;
63 }
64
65 bool SerialAsyncApiFunction::Respond() {
66 return error_.empty();
67 }
68
69 SerialConnection* SerialAsyncApiFunction::GetSerialConnection(
70 int api_resource_id) {
71 return manager_->Get(extension_->id(), api_resource_id);
72 }
73
74 void SerialAsyncApiFunction::RemoveSerialConnection(int api_resource_id) {
75 manager_->Remove(extension_->id(), api_resource_id);
76 }
77
78 SerialGetDevicesFunction::SerialGetDevicesFunction() {}
79
80 bool SerialGetDevicesFunction::Prepare() {
81 set_work_thread_id(BrowserThread::FILE);
82 return true;
83 }
84
85 void SerialGetDevicesFunction::Work() {
86 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
87
88 scoped_ptr<device::SerialDeviceEnumerator> enumerator =
89 device::SerialDeviceEnumerator::Create();
90 mojo::Array<device::serial::DeviceInfoPtr> devices = enumerator->GetDevices();
91 results_ = serial::GetDevices::Results::Create(
92 devices.To<std::vector<linked_ptr<serial::DeviceInfo> > >());
93 }
94
95 SerialConnectFunction::SerialConnectFunction() {}
96
97 SerialConnectFunction::~SerialConnectFunction() {}
98
99 bool SerialConnectFunction::Prepare() {
100 params_ = serial::Connect::Params::Create(*args_);
101 EXTENSION_FUNCTION_VALIDATE(params_.get());
102
103 // Fill in any omitted options to ensure a known initial configuration.
104 if (!params_->options.get())
105 params_->options.reset(new serial::ConnectionOptions());
106 serial::ConnectionOptions* options = params_->options.get();
107
108 SetDefaultScopedPtrValue(options->persistent, false);
109 SetDefaultScopedPtrValue(options->buffer_size, kDefaultBufferSize);
110 SetDefaultScopedPtrValue(options->bitrate, kDefaultBitrate);
111 SetDefaultScopedPtrValue(options->cts_flow_control, false);
112 SetDefaultScopedPtrValue(options->receive_timeout, kDefaultReceiveTimeout);
113 SetDefaultScopedPtrValue(options->send_timeout, kDefaultSendTimeout);
114
115 if (options->data_bits == serial::DATA_BITS_NONE)
116 options->data_bits = kDefaultDataBits;
117 if (options->parity_bit == serial::PARITY_BIT_NONE)
118 options->parity_bit = kDefaultParityBit;
119 if (options->stop_bits == serial::STOP_BITS_NONE)
120 options->stop_bits = kDefaultStopBits;
121
122 serial_event_dispatcher_ = SerialEventDispatcher::Get(browser_context());
123 DCHECK(serial_event_dispatcher_);
124
125 return true;
126 }
127
128 void SerialConnectFunction::AsyncWorkStart() {
129 DCHECK_CURRENTLY_ON(BrowserThread::IO);
130 connection_ = CreateSerialConnection(params_->path, extension_->id());
131 connection_->Open(base::Bind(&SerialConnectFunction::OnConnected, this));
132 }
133
134 void SerialConnectFunction::OnConnected(bool success) {
135 DCHECK(connection_);
136
137 if (success) {
138 if (!connection_->Configure(*params_->options.get())) {
139 delete connection_;
140 connection_ = NULL;
141 }
142 } else {
143 delete connection_;
144 connection_ = NULL;
145 }
146
147 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
148 base::Bind(&SerialConnectFunction::FinishConnect,
149 this));
150 }
151
152 void SerialConnectFunction::FinishConnect() {
153 DCHECK_CURRENTLY_ON(BrowserThread::IO);
154 if (!connection_) {
155 error_ = kErrorConnectFailed;
156 } else {
157 int id = manager_->Add(connection_);
158 serial::ConnectionInfo info;
159 info.connection_id = id;
160 if (connection_->GetInfo(&info)) {
161 serial_event_dispatcher_->PollConnection(extension_->id(), id);
162 results_ = serial::Connect::Results::Create(info);
163 } else {
164 RemoveSerialConnection(id);
165 error_ = kErrorConnectFailed;
166 }
167 }
168 AsyncWorkCompleted();
169 }
170
171 SerialConnection* SerialConnectFunction::CreateSerialConnection(
172 const std::string& port, const std::string& extension_id) const {
173 return new SerialConnection(port, extension_id);
174 }
175
176 SerialUpdateFunction::SerialUpdateFunction() {}
177
178 SerialUpdateFunction::~SerialUpdateFunction() {}
179
180 bool SerialUpdateFunction::Prepare() {
181 params_ = serial::Update::Params::Create(*args_);
182 EXTENSION_FUNCTION_VALIDATE(params_.get());
183
184 return true;
185 }
186
187 void SerialUpdateFunction::Work() {
188 SerialConnection* connection = GetSerialConnection(params_->connection_id);
189 if (!connection) {
190 error_ = kErrorSerialConnectionNotFound;
191 return;
192 }
193 bool success = connection->Configure(params_->options);
194 results_ = serial::Update::Results::Create(success);
195 }
196
197 SerialDisconnectFunction::SerialDisconnectFunction() {}
198
199 SerialDisconnectFunction::~SerialDisconnectFunction() {}
200
201 bool SerialDisconnectFunction::Prepare() {
202 params_ = serial::Disconnect::Params::Create(*args_);
203 EXTENSION_FUNCTION_VALIDATE(params_.get());
204
205 return true;
206 }
207
208 void SerialDisconnectFunction::Work() {
209 SerialConnection* connection = GetSerialConnection(params_->connection_id);
210 if (!connection) {
211 error_ = kErrorSerialConnectionNotFound;
212 return;
213 }
214 RemoveSerialConnection(params_->connection_id);
215 results_ = serial::Disconnect::Results::Create(true);
216 }
217
218 SerialSendFunction::SerialSendFunction() {}
219
220 SerialSendFunction::~SerialSendFunction() {}
221
222 bool SerialSendFunction::Prepare() {
223 params_ = serial::Send::Params::Create(*args_);
224 EXTENSION_FUNCTION_VALIDATE(params_.get());
225
226 return true;
227 }
228
229 void SerialSendFunction::AsyncWorkStart() {
230 SerialConnection* connection = GetSerialConnection(params_->connection_id);
231 if (!connection) {
232 error_ = kErrorSerialConnectionNotFound;
233 AsyncWorkCompleted();
234 return;
235 }
236
237 if (!connection->Send(params_->data,
238 base::Bind(&SerialSendFunction::OnSendComplete,
239 this))) {
240 OnSendComplete(0, serial::SEND_ERROR_PENDING);
241 }
242 }
243
244 void SerialSendFunction::OnSendComplete(int bytes_sent,
245 serial::SendError error) {
246 serial::SendInfo send_info;
247 send_info.bytes_sent = bytes_sent;
248 send_info.error = error;
249 results_ = serial::Send::Results::Create(send_info);
250 AsyncWorkCompleted();
251 }
252
253 SerialFlushFunction::SerialFlushFunction() {}
254
255 SerialFlushFunction::~SerialFlushFunction() {}
256
257 bool SerialFlushFunction::Prepare() {
258 params_ = serial::Flush::Params::Create(*args_);
259 EXTENSION_FUNCTION_VALIDATE(params_.get());
260 return true;
261 }
262
263 void SerialFlushFunction::Work() {
264 SerialConnection* connection = GetSerialConnection(params_->connection_id);
265 if (!connection) {
266 error_ = kErrorSerialConnectionNotFound;
267 return;
268 }
269
270 bool success = connection->Flush();
271 results_ = serial::Flush::Results::Create(success);
272 }
273
274 SerialSetPausedFunction::SerialSetPausedFunction() {}
275
276 SerialSetPausedFunction::~SerialSetPausedFunction() {}
277
278 bool SerialSetPausedFunction::Prepare() {
279 params_ = serial::SetPaused::Params::Create(*args_);
280 EXTENSION_FUNCTION_VALIDATE(params_.get());
281
282 serial_event_dispatcher_ = SerialEventDispatcher::Get(browser_context());
283 DCHECK(serial_event_dispatcher_);
284 return true;
285 }
286
287 void SerialSetPausedFunction::Work() {
288 SerialConnection* connection = GetSerialConnection(params_->connection_id);
289 if (!connection) {
290 error_ = kErrorSerialConnectionNotFound;
291 return;
292 }
293
294 if (params_->paused != connection->paused()) {
295 connection->set_paused(params_->paused);
296 if (!params_->paused) {
297 serial_event_dispatcher_->PollConnection(extension_->id(),
298 params_->connection_id);
299 }
300 }
301
302 results_ = serial::SetPaused::Results::Create();
303 }
304
305 SerialGetInfoFunction::SerialGetInfoFunction() {}
306
307 SerialGetInfoFunction::~SerialGetInfoFunction() {}
308
309 bool SerialGetInfoFunction::Prepare() {
310 params_ = serial::GetInfo::Params::Create(*args_);
311 EXTENSION_FUNCTION_VALIDATE(params_.get());
312
313 return true;
314 }
315
316 void SerialGetInfoFunction::Work() {
317 SerialConnection* connection = GetSerialConnection(params_->connection_id);
318 if (!connection) {
319 error_ = kErrorSerialConnectionNotFound;
320 return;
321 }
322
323 serial::ConnectionInfo info;
324 info.connection_id = params_->connection_id;
325 connection->GetInfo(&info);
326 results_ = serial::GetInfo::Results::Create(info);
327 }
328
329 SerialGetConnectionsFunction::SerialGetConnectionsFunction() {}
330
331 SerialGetConnectionsFunction::~SerialGetConnectionsFunction() {}
332
333 bool SerialGetConnectionsFunction::Prepare() {
334 return true;
335 }
336
337 void SerialGetConnectionsFunction::Work() {
338 std::vector<linked_ptr<serial::ConnectionInfo> > infos;
339 const base::hash_set<int>* connection_ids = manager_->GetResourceIds(
340 extension_->id());
341 if (connection_ids) {
342 for (base::hash_set<int>::const_iterator it = connection_ids->begin();
343 it != connection_ids->end(); ++it) {
344 int connection_id = *it;
345 SerialConnection *connection = GetSerialConnection(connection_id);
346 if (connection) {
347 linked_ptr<serial::ConnectionInfo> info(new serial::ConnectionInfo());
348 info->connection_id = connection_id;
349 connection->GetInfo(info.get());
350 infos.push_back(info);
351 }
352 }
353 }
354 results_ = serial::GetConnections::Results::Create(infos);
355 }
356
357 SerialGetControlSignalsFunction::SerialGetControlSignalsFunction() {}
358
359 SerialGetControlSignalsFunction::~SerialGetControlSignalsFunction() {}
360
361 bool SerialGetControlSignalsFunction::Prepare() {
362 params_ = serial::GetControlSignals::Params::Create(*args_);
363 EXTENSION_FUNCTION_VALIDATE(params_.get());
364
365 return true;
366 }
367
368 void SerialGetControlSignalsFunction::Work() {
369 SerialConnection* connection = GetSerialConnection(params_->connection_id);
370 if (!connection) {
371 error_ = kErrorSerialConnectionNotFound;
372 return;
373 }
374
375 serial::DeviceControlSignals signals;
376 if (!connection->GetControlSignals(&signals)) {
377 error_ = kErrorGetControlSignalsFailed;
378 return;
379 }
380
381 results_ = serial::GetControlSignals::Results::Create(signals);
382 }
383
384 SerialSetControlSignalsFunction::SerialSetControlSignalsFunction() {}
385
386 SerialSetControlSignalsFunction::~SerialSetControlSignalsFunction() {}
387
388 bool SerialSetControlSignalsFunction::Prepare() {
389 params_ = serial::SetControlSignals::Params::Create(*args_);
390 EXTENSION_FUNCTION_VALIDATE(params_.get());
391
392 return true;
393 }
394
395 void SerialSetControlSignalsFunction::Work() {
396 SerialConnection* connection = GetSerialConnection(params_->connection_id);
397 if (!connection) {
398 error_ = kErrorSerialConnectionNotFound;
399 return;
400 }
401
402 bool success = connection->SetControlSignals(params_->signals);
403 results_ = serial::SetControlSignals::Results::Create(success);
404 }
405
406 } // namespace api
407
408 } // namespace extensions
409
410 namespace mojo {
411
412 // static
413 linked_ptr<extensions::api::serial::DeviceInfo>
414 TypeConverter<device::serial::DeviceInfoPtr,
415 linked_ptr<extensions::api::serial::DeviceInfo> >::
416 ConvertTo(const device::serial::DeviceInfoPtr& device) {
417 linked_ptr<extensions::api::serial::DeviceInfo> info(
418 new extensions::api::serial::DeviceInfo);
419 info->path = device->path;
420 if (device->has_vendor_id)
421 info->vendor_id.reset(new int(static_cast<int>(device->vendor_id)));
422 if (device->has_product_id)
423 info->product_id.reset(new int(static_cast<int>(device->product_id)));
424 if (device->display_name)
425 info->display_name.reset(new std::string(device->display_name));
426 return info;
427 }
428
429 } // namespace mojo
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/serial/serial_api.h ('k') | chrome/browser/extensions/api/serial/serial_apitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698