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