Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / serial / serial_api.cc
1 // Copyright (c) 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/extension_system.h"
11 #include "chrome/browser/extensions/api/serial/serial_connection.h"
12 #include "chrome/browser/extensions/api/serial/serial_event_dispatcher.h"
13 #include "chrome/browser/extensions/api/serial/serial_port_enumerator.h"
14 #include "chrome/common/extensions/api/serial.h"
15 #include "content/public/browser/browser_thread.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   std::vector<linked_ptr<serial::DeviceInfo> > devices;
88   SerialPortEnumerator::StringSet port_names =
89       SerialPortEnumerator::GenerateValidSerialPortNames();
90   for (SerialPortEnumerator::StringSet::const_iterator iter =
91           port_names.begin();
92        iter != port_names.end();
93        ++iter) {
94     linked_ptr<serial::DeviceInfo> info(new serial::DeviceInfo);
95     info->path = *iter;
96     devices.push_back(info);
97   }
98   results_ = serial::GetDevices::Results::Create(devices);
99 }
100
101 SerialConnectFunction::SerialConnectFunction() {}
102
103 SerialConnectFunction::~SerialConnectFunction() {}
104
105 bool SerialConnectFunction::Prepare() {
106   params_ = serial::Connect::Params::Create(*args_);
107   EXTENSION_FUNCTION_VALIDATE(params_.get());
108
109   // Fill in any omitted options to ensure a known initial configuration.
110   if (!params_->options.get())
111     params_->options.reset(new serial::ConnectionOptions());
112   serial::ConnectionOptions* options = params_->options.get();
113
114   SetDefaultScopedPtrValue(options->persistent, false);
115   SetDefaultScopedPtrValue(options->buffer_size, kDefaultBufferSize);
116   SetDefaultScopedPtrValue(options->bitrate, kDefaultBitrate);
117   SetDefaultScopedPtrValue(options->cts_flow_control, false);
118   SetDefaultScopedPtrValue(options->receive_timeout, kDefaultReceiveTimeout);
119   SetDefaultScopedPtrValue(options->send_timeout, kDefaultSendTimeout);
120
121   if (options->data_bits == serial::DATA_BITS_NONE)
122     options->data_bits = kDefaultDataBits;
123   if (options->parity_bit == serial::PARITY_BIT_NONE)
124     options->parity_bit = kDefaultParityBit;
125   if (options->stop_bits == serial::STOP_BITS_NONE)
126     options->stop_bits = kDefaultStopBits;
127
128   serial_event_dispatcher_ = SerialEventDispatcher::Get(GetProfile());
129   DCHECK(serial_event_dispatcher_);
130
131   return true;
132 }
133
134 void SerialConnectFunction::AsyncWorkStart() {
135   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
136   connection_ = CreateSerialConnection(params_->path, extension_->id());
137   connection_->Open(base::Bind(&SerialConnectFunction::OnConnected, this));
138 }
139
140 void SerialConnectFunction::OnConnected(bool success) {
141   DCHECK(connection_);
142
143   if (success) {
144     if (!connection_->Configure(*params_->options.get())) {
145       connection_->Close();
146       delete connection_;
147       connection_ = NULL;
148     }
149   } else {
150     delete connection_;
151     connection_ = NULL;
152   }
153
154   BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
155                           base::Bind(&SerialConnectFunction::FinishConnect,
156                                      this));
157 }
158
159 void SerialConnectFunction::FinishConnect() {
160   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
161   if (!connection_) {
162     error_ = kErrorConnectFailed;
163   } else {
164     int id = manager_->Add(connection_);
165     serial::ConnectionInfo info;
166     info.connection_id = id;
167     if (connection_->GetInfo(&info)) {
168       serial_event_dispatcher_->PollConnection(extension_->id(), id);
169       results_ = serial::Connect::Results::Create(info);
170     } else {
171       connection_->Close();
172       RemoveSerialConnection(id);
173       error_ = kErrorConnectFailed;
174     }
175   }
176   AsyncWorkCompleted();
177 }
178
179 SerialConnection* SerialConnectFunction::CreateSerialConnection(
180     const std::string& port, const std::string& extension_id) const {
181   return new SerialConnection(port, extension_id);
182 }
183
184 SerialUpdateFunction::SerialUpdateFunction() {}
185
186 SerialUpdateFunction::~SerialUpdateFunction() {}
187
188 bool SerialUpdateFunction::Prepare() {
189   params_ = serial::Update::Params::Create(*args_);
190   EXTENSION_FUNCTION_VALIDATE(params_.get());
191
192   return true;
193 }
194
195 void SerialUpdateFunction::Work() {
196   SerialConnection* connection = GetSerialConnection(params_->connection_id);
197   if (!connection) {
198     error_ = kErrorSerialConnectionNotFound;
199     return;
200   }
201   bool success = connection->Configure(params_->options);
202   results_ = serial::Update::Results::Create(success);
203 }
204
205 SerialDisconnectFunction::SerialDisconnectFunction() {}
206
207 SerialDisconnectFunction::~SerialDisconnectFunction() {}
208
209 bool SerialDisconnectFunction::Prepare() {
210   params_ = serial::Disconnect::Params::Create(*args_);
211   EXTENSION_FUNCTION_VALIDATE(params_.get());
212
213   return true;
214 }
215
216 void SerialDisconnectFunction::Work() {
217   SerialConnection* connection = GetSerialConnection(params_->connection_id);
218   if (!connection) {
219     error_ = kErrorSerialConnectionNotFound;
220     return;
221   }
222   connection->Close();
223   RemoveSerialConnection(params_->connection_id);
224   results_ = serial::Disconnect::Results::Create(true);
225 }
226
227 SerialSendFunction::SerialSendFunction() {}
228
229 SerialSendFunction::~SerialSendFunction() {}
230
231 bool SerialSendFunction::Prepare() {
232   params_ = serial::Send::Params::Create(*args_);
233   EXTENSION_FUNCTION_VALIDATE(params_.get());
234
235   return true;
236 }
237
238 void SerialSendFunction::AsyncWorkStart() {
239   SerialConnection* connection = GetSerialConnection(params_->connection_id);
240   if (!connection) {
241     error_ = kErrorSerialConnectionNotFound;
242     AsyncWorkCompleted();
243     return;
244   }
245
246   if (!connection->Send(params_->data,
247                         base::Bind(&SerialSendFunction::OnSendComplete,
248                                    this))) {
249     OnSendComplete(0, serial::SEND_ERROR_PENDING);
250   }
251 }
252
253 void SerialSendFunction::OnSendComplete(int bytes_sent,
254                                         serial::SendError error) {
255   serial::SendInfo send_info;
256   send_info.bytes_sent = bytes_sent;
257   send_info.error = error;
258   results_ = serial::Send::Results::Create(send_info);
259   AsyncWorkCompleted();
260 }
261
262 SerialFlushFunction::SerialFlushFunction() {}
263
264 SerialFlushFunction::~SerialFlushFunction() {}
265
266 bool SerialFlushFunction::Prepare() {
267   params_ = serial::Flush::Params::Create(*args_);
268   EXTENSION_FUNCTION_VALIDATE(params_.get());
269   return true;
270 }
271
272 void SerialFlushFunction::Work() {
273   SerialConnection* connection = GetSerialConnection(params_->connection_id);
274   if (!connection) {
275     error_ = kErrorSerialConnectionNotFound;
276     return;
277   }
278
279   bool success = connection->Flush();
280   results_ = serial::Flush::Results::Create(success);
281 }
282
283 SerialSetPausedFunction::SerialSetPausedFunction() {}
284
285 SerialSetPausedFunction::~SerialSetPausedFunction() {}
286
287 bool SerialSetPausedFunction::Prepare() {
288   params_ = serial::SetPaused::Params::Create(*args_);
289   EXTENSION_FUNCTION_VALIDATE(params_.get());
290
291   serial_event_dispatcher_ = SerialEventDispatcher::Get(GetProfile());
292   DCHECK(serial_event_dispatcher_);
293   return true;
294 }
295
296 void SerialSetPausedFunction::Work() {
297   SerialConnection* connection = GetSerialConnection(params_->connection_id);
298   if (!connection) {
299     error_ = kErrorSerialConnectionNotFound;
300     return;
301   }
302
303   if (params_->paused != connection->paused()) {
304     connection->set_paused(params_->paused);
305     if (!params_->paused) {
306       serial_event_dispatcher_->PollConnection(extension_->id(),
307                                                params_->connection_id);
308     }
309   }
310
311   results_ = serial::SetPaused::Results::Create();
312 }
313
314 SerialGetInfoFunction::SerialGetInfoFunction() {}
315
316 SerialGetInfoFunction::~SerialGetInfoFunction() {}
317
318 bool SerialGetInfoFunction::Prepare() {
319   params_ = serial::GetInfo::Params::Create(*args_);
320   EXTENSION_FUNCTION_VALIDATE(params_.get());
321
322   return true;
323 }
324
325 void SerialGetInfoFunction::Work() {
326   SerialConnection* connection = GetSerialConnection(params_->connection_id);
327   if (!connection) {
328     error_ = kErrorSerialConnectionNotFound;
329     return;
330   }
331
332   serial::ConnectionInfo info;
333   info.connection_id = params_->connection_id;
334   connection->GetInfo(&info);
335   results_ = serial::GetInfo::Results::Create(info);
336 }
337
338 SerialGetConnectionsFunction::SerialGetConnectionsFunction() {}
339
340 SerialGetConnectionsFunction::~SerialGetConnectionsFunction() {}
341
342 bool SerialGetConnectionsFunction::Prepare() {
343   return true;
344 }
345
346 void SerialGetConnectionsFunction::Work() {
347   std::vector<linked_ptr<serial::ConnectionInfo> > infos;
348   const base::hash_set<int>* connection_ids = manager_->GetResourceIds(
349       extension_->id());
350   if (connection_ids) {
351     for (base::hash_set<int>::const_iterator it = connection_ids->begin();
352          it != connection_ids->end(); ++it) {
353       int connection_id = *it;
354       SerialConnection *connection = GetSerialConnection(connection_id);
355       if (connection) {
356         linked_ptr<serial::ConnectionInfo> info(new serial::ConnectionInfo());
357         info->connection_id = connection_id;
358         connection->GetInfo(info.get());
359         infos.push_back(info);
360       }
361     }
362   }
363   results_ = serial::GetConnections::Results::Create(infos);
364 }
365
366 SerialGetControlSignalsFunction::SerialGetControlSignalsFunction() {}
367
368 SerialGetControlSignalsFunction::~SerialGetControlSignalsFunction() {}
369
370 bool SerialGetControlSignalsFunction::Prepare() {
371   params_ = serial::GetControlSignals::Params::Create(*args_);
372   EXTENSION_FUNCTION_VALIDATE(params_.get());
373
374   return true;
375 }
376
377 void SerialGetControlSignalsFunction::Work() {
378   SerialConnection* connection = GetSerialConnection(params_->connection_id);
379   if (!connection) {
380     error_ = kErrorSerialConnectionNotFound;
381     return;
382   }
383
384   serial::DeviceControlSignals signals;
385   if (!connection->GetControlSignals(&signals)) {
386     error_ = kErrorGetControlSignalsFailed;
387     return;
388   }
389
390   results_ = serial::GetControlSignals::Results::Create(signals);
391 }
392
393 SerialSetControlSignalsFunction::SerialSetControlSignalsFunction() {}
394
395 SerialSetControlSignalsFunction::~SerialSetControlSignalsFunction() {}
396
397 bool SerialSetControlSignalsFunction::Prepare() {
398   params_ = serial::SetControlSignals::Params::Create(*args_);
399   EXTENSION_FUNCTION_VALIDATE(params_.get());
400
401   return true;
402 }
403
404 void SerialSetControlSignalsFunction::Work() {
405   SerialConnection* connection = GetSerialConnection(params_->connection_id);
406   if (!connection) {
407     error_ = kErrorSerialConnectionNotFound;
408     return;
409   }
410
411   bool success = connection->SetControlSignals(params_->signals);
412   results_ = serial::SetControlSignals::Results::Create(success);
413 }
414
415 }  // namespace api
416
417 }  // namespace extensions