Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / usb / usb_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/usb/usb_api.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "chrome/browser/extensions/api/usb/usb_device_resource.h"
13 #include "chrome/browser/usb/usb_device_handle.h"
14 #include "chrome/browser/usb/usb_service.h"
15 #include "chrome/common/extensions/api/usb.h"
16 #include "extensions/browser/extension_system.h"
17 #include "extensions/common/permissions/permissions_data.h"
18 #include "extensions/common/permissions/usb_device_permission.h"
19
20 namespace usb = extensions::api::usb;
21 namespace BulkTransfer = usb::BulkTransfer;
22 namespace ClaimInterface = usb::ClaimInterface;
23 namespace CloseDevice = usb::CloseDevice;
24 namespace ControlTransfer = usb::ControlTransfer;
25 namespace FindDevices = usb::FindDevices;
26 namespace GetDevices = usb::GetDevices;
27 namespace InterruptTransfer = usb::InterruptTransfer;
28 namespace IsochronousTransfer = usb::IsochronousTransfer;
29 namespace ListInterfaces = usb::ListInterfaces;
30 namespace OpenDevice = usb::OpenDevice;
31 namespace ReleaseInterface = usb::ReleaseInterface;
32 namespace RequestAccess = usb::RequestAccess;
33 namespace ResetDevice = usb::ResetDevice;
34 namespace SetInterfaceAlternateSetting = usb::SetInterfaceAlternateSetting;
35
36 using content::BrowserThread;
37 using std::string;
38 using std::vector;
39 using usb::ControlTransferInfo;
40 using usb::ConnectionHandle;
41 using usb::Device;
42 using usb::Direction;
43 using usb::EndpointDescriptor;
44 using usb::GenericTransferInfo;
45 using usb::InterfaceDescriptor;
46 using usb::IsochronousTransferInfo;
47 using usb::Recipient;
48 using usb::RequestType;
49 using usb::SynchronizationType;
50 using usb::TransferType;
51 using usb::UsageType;
52
53 typedef std::vector<scoped_refptr<UsbDevice> > DeviceVector;
54 typedef scoped_ptr<DeviceVector> ScopedDeviceVector;
55
56 namespace {
57
58 const char kDataKey[] = "data";
59 const char kResultCodeKey[] = "resultCode";
60
61 const char kErrorInitService[] = "Failed to initialize USB service.";
62
63 const char kErrorOpen[] = "Failed to open device.";
64 const char kErrorCancelled[] = "Transfer was cancelled.";
65 const char kErrorDisconnect[] = "Device disconnected.";
66 const char kErrorGeneric[] = "Transfer failed.";
67 #if !defined(OS_CHROMEOS)
68 const char kErrorNotSupported[] = "Not supported on this platform.";
69 #endif
70 const char kErrorOverflow[] = "Inbound transfer overflow.";
71 const char kErrorStalled[] = "Transfer stalled.";
72 const char kErrorTimeout[] = "Transfer timed out.";
73 const char kErrorTransferLength[] = "Transfer length is insufficient.";
74
75 const char kErrorCannotListInterfaces[] = "Error listing interfaces.";
76 const char kErrorCannotClaimInterface[] = "Error claiming interface.";
77 const char kErrorCannotReleaseInterface[] = "Error releasing interface.";
78 const char kErrorCannotSetInterfaceAlternateSetting[] =
79     "Error setting alternate interface setting.";
80 const char kErrorConvertDirection[] = "Invalid transfer direction.";
81 const char kErrorConvertRecipient[] = "Invalid transfer recipient.";
82 const char kErrorConvertRequestType[] = "Invalid request type.";
83 const char kErrorConvertSynchronizationType[] = "Invalid synchronization type";
84 const char kErrorConvertTransferType[] = "Invalid endpoint type.";
85 const char kErrorConvertUsageType[] = "Invalid usage type.";
86 const char kErrorMalformedParameters[] = "Error parsing parameters.";
87 const char kErrorNoDevice[] = "No such device.";
88 const char kErrorPermissionDenied[] =
89     "Permission to access device was denied";
90 const char kErrorInvalidTransferLength[] =
91     "Transfer length must be a positive number less than 104,857,600.";
92 const char kErrorInvalidNumberOfPackets[] =
93     "Number of packets must be a positive number less than 4,194,304.";
94 const char kErrorInvalidPacketLength[] = "Packet length must be a "
95     "positive number less than 65,536.";
96 const char kErrorResetDevice[] =
97     "Error resetting the device. The device has been closed.";
98
99 const size_t kMaxTransferLength = 100 * 1024 * 1024;
100 const int kMaxPackets = 4 * 1024 * 1024;
101 const int kMaxPacketLength = 64 * 1024;
102
103 UsbDevice* g_device_for_test = NULL;
104
105 bool ConvertDirectionToApi(const UsbEndpointDirection& input,
106                            Direction* output) {
107   switch (input) {
108     case USB_DIRECTION_INBOUND:
109       *output = usb::DIRECTION_IN;
110       return true;
111     case USB_DIRECTION_OUTBOUND:
112       *output = usb::DIRECTION_OUT;
113       return true;
114     default:
115       NOTREACHED();
116       return false;
117   }
118 }
119
120 bool ConvertSynchronizationTypeToApi(const UsbSynchronizationType& input,
121                                      usb::SynchronizationType* output) {
122   switch (input) {
123     case USB_SYNCHRONIZATION_NONE:
124       *output = usb::SYNCHRONIZATION_TYPE_NONE;
125       return true;
126     case USB_SYNCHRONIZATION_ASYNCHRONOUS:
127       *output = usb::SYNCHRONIZATION_TYPE_ASYNCHRONOUS;
128       return true;
129     case USB_SYNCHRONIZATION_ADAPTIVE:
130       *output = usb::SYNCHRONIZATION_TYPE_ADAPTIVE;
131       return true;
132     case USB_SYNCHRONIZATION_SYNCHRONOUS:
133       *output = usb::SYNCHRONIZATION_TYPE_SYNCHRONOUS;
134       return true;
135     default:
136       NOTREACHED();
137       return false;
138   }
139 }
140
141 bool ConvertTransferTypeToApi(
142     const UsbTransferType& input,
143     usb::TransferType* output) {
144   switch (input) {
145     case USB_TRANSFER_CONTROL:
146       *output = usb::TRANSFER_TYPE_CONTROL;
147       return true;
148     case USB_TRANSFER_INTERRUPT:
149       *output = usb::TRANSFER_TYPE_INTERRUPT;
150       return true;
151     case USB_TRANSFER_ISOCHRONOUS:
152       *output = usb::TRANSFER_TYPE_ISOCHRONOUS;
153       return true;
154     case USB_TRANSFER_BULK:
155       *output = usb::TRANSFER_TYPE_BULK;
156       return true;
157     default:
158       NOTREACHED();
159       return false;
160   }
161 }
162
163 bool ConvertUsageTypeToApi(const UsbUsageType& input, usb::UsageType* output) {
164   switch (input) {
165     case USB_USAGE_DATA:
166       *output = usb::USAGE_TYPE_DATA;
167       return true;
168     case USB_USAGE_FEEDBACK:
169       *output = usb::USAGE_TYPE_FEEDBACK;
170       return true;
171     case USB_USAGE_EXPLICIT_FEEDBACK:
172       *output = usb::USAGE_TYPE_EXPLICITFEEDBACK;
173       return true;
174     default:
175       NOTREACHED();
176       return false;
177   }
178 }
179
180 bool ConvertDirection(const Direction& input,
181                       UsbEndpointDirection* output) {
182   switch (input) {
183     case usb::DIRECTION_IN:
184       *output = USB_DIRECTION_INBOUND;
185       return true;
186     case usb::DIRECTION_OUT:
187       *output = USB_DIRECTION_OUTBOUND;
188       return true;
189     default:
190       NOTREACHED();
191       return false;
192   }
193 }
194
195 bool ConvertRequestType(const RequestType& input,
196                         UsbDeviceHandle::TransferRequestType* output) {
197   switch (input) {
198     case usb::REQUEST_TYPE_STANDARD:
199       *output = UsbDeviceHandle::STANDARD;
200       return true;
201     case usb::REQUEST_TYPE_CLASS:
202       *output = UsbDeviceHandle::CLASS;
203       return true;
204     case usb::REQUEST_TYPE_VENDOR:
205       *output = UsbDeviceHandle::VENDOR;
206       return true;
207     case usb::REQUEST_TYPE_RESERVED:
208       *output = UsbDeviceHandle::RESERVED;
209       return true;
210     default:
211       NOTREACHED();
212       return false;
213   }
214 }
215
216 bool ConvertRecipient(const Recipient& input,
217                       UsbDeviceHandle::TransferRecipient* output) {
218   switch (input) {
219     case usb::RECIPIENT_DEVICE:
220       *output = UsbDeviceHandle::DEVICE;
221       return true;
222     case usb::RECIPIENT_INTERFACE:
223       *output = UsbDeviceHandle::INTERFACE;
224       return true;
225     case usb::RECIPIENT_ENDPOINT:
226       *output = UsbDeviceHandle::ENDPOINT;
227       return true;
228     case usb::RECIPIENT_OTHER:
229       *output = UsbDeviceHandle::OTHER;
230       return true;
231     default:
232       NOTREACHED();
233       return false;
234   }
235 }
236
237 template<class T>
238 bool GetTransferSize(const T& input, size_t* output) {
239   if (input.direction == usb::DIRECTION_IN) {
240     const int* length = input.length.get();
241     if (length && *length >= 0 &&
242         static_cast<size_t>(*length) < kMaxTransferLength) {
243       *output = *length;
244       return true;
245     }
246   } else if (input.direction == usb::DIRECTION_OUT) {
247     if (input.data.get()) {
248       *output = input.data->size();
249       return true;
250     }
251   }
252   return false;
253 }
254
255 template<class T>
256 scoped_refptr<net::IOBuffer> CreateBufferForTransfer(
257     const T& input, UsbEndpointDirection direction, size_t size) {
258
259   if (size >= kMaxTransferLength)
260     return NULL;
261
262   // Allocate a |size|-bytes buffer, or a one-byte buffer if |size| is 0. This
263   // is due to an impedance mismatch between IOBuffer and URBs. An IOBuffer
264   // cannot represent a zero-length buffer, while an URB can.
265   scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(std::max(
266       static_cast<size_t>(1), size));
267
268   if (direction == USB_DIRECTION_INBOUND) {
269     return buffer;
270   } else if (direction == USB_DIRECTION_OUTBOUND) {
271     if (input.data.get() && size <= input.data->size()) {
272       memcpy(buffer->data(), input.data->data(), size);
273       return buffer;
274     }
275   }
276   NOTREACHED();
277   return NULL;
278 }
279
280 const char* ConvertTransferStatusToErrorString(const UsbTransferStatus status) {
281   switch (status) {
282     case USB_TRANSFER_COMPLETED:
283       return "";
284     case USB_TRANSFER_ERROR:
285       return kErrorGeneric;
286     case USB_TRANSFER_TIMEOUT:
287       return kErrorTimeout;
288     case USB_TRANSFER_CANCELLED:
289       return kErrorCancelled;
290     case USB_TRANSFER_STALLED:
291       return kErrorStalled;
292     case USB_TRANSFER_DISCONNECT:
293       return kErrorDisconnect;
294     case USB_TRANSFER_OVERFLOW:
295       return kErrorOverflow;
296     case USB_TRANSFER_LENGTH_SHORT:
297       return kErrorTransferLength;
298     default:
299       NOTREACHED();
300       return "";
301   }
302 }
303
304 #if defined(OS_CHROMEOS)
305 void RequestUsbDevicesAccessHelper(
306     ScopedDeviceVector devices,
307     std::vector<scoped_refptr<UsbDevice> >::iterator i,
308     int interface_id,
309     const base::Callback<void(ScopedDeviceVector result)>& callback,
310     bool success) {
311   if (success) {
312     ++i;
313   } else {
314     i = devices->erase(i);
315   }
316   if (i == devices->end()) {
317     callback.Run(devices.Pass());
318     return;
319   }
320   (*i)->RequestUsbAcess(interface_id, base::Bind(RequestUsbDevicesAccessHelper,
321                                                  base::Passed(devices.Pass()),
322                                                  i, interface_id, callback));
323 }
324
325 void RequestUsbDevicesAccess(
326     ScopedDeviceVector devices,
327     int interface_id,
328     const base::Callback<void(ScopedDeviceVector result)>& callback) {
329   if (devices->empty()) {
330     callback.Run(devices.Pass());
331     return;
332   }
333   std::vector<scoped_refptr<UsbDevice> >::iterator i = devices->begin();
334   (*i)->RequestUsbAcess(
335       interface_id,
336       base::Bind(RequestUsbDevicesAccessHelper, base::Passed(devices.Pass()),
337                  i, interface_id, callback));
338 }
339 #endif  // OS_CHROMEOS
340
341 base::DictionaryValue* CreateTransferInfo(
342     UsbTransferStatus status,
343     scoped_refptr<net::IOBuffer> data,
344     size_t length) {
345   base::DictionaryValue* result = new base::DictionaryValue();
346   result->SetInteger(kResultCodeKey, status);
347   result->Set(kDataKey, base::BinaryValue::CreateWithCopiedBuffer(data->data(),
348                                                                   length));
349   return result;
350 }
351
352 base::Value* PopulateConnectionHandle(int handle, int vendor_id,
353                                       int product_id) {
354   ConnectionHandle result;
355   result.handle = handle;
356   result.vendor_id = vendor_id;
357   result.product_id = product_id;
358   return result.ToValue().release();
359 }
360
361 base::Value* PopulateDevice(UsbDevice* device) {
362   Device result;
363   result.device = device->unique_id();
364   result.vendor_id = device->vendor_id();
365   result.product_id = device->product_id();
366   return result.ToValue().release();
367 }
368
369 base::Value* PopulateInterfaceDescriptor(
370     int interface_number,
371     int alternate_setting,
372     int interface_class,
373     int interface_subclass,
374     int interface_protocol,
375     std::vector<linked_ptr<EndpointDescriptor> >* endpoints) {
376   InterfaceDescriptor descriptor;
377   descriptor.interface_number = interface_number;
378   descriptor.alternate_setting = alternate_setting;
379   descriptor.interface_class = interface_class;
380   descriptor.interface_subclass = interface_subclass;
381   descriptor.interface_protocol = interface_protocol;
382   descriptor.endpoints = *endpoints;
383   return descriptor.ToValue().release();
384 }
385
386 }  // namespace
387
388 namespace extensions {
389
390 UsbAsyncApiFunction::UsbAsyncApiFunction()
391     : manager_(NULL) {
392 }
393
394 UsbAsyncApiFunction::~UsbAsyncApiFunction() {
395 }
396
397 bool UsbAsyncApiFunction::PrePrepare() {
398   manager_ = ApiResourceManager<UsbDeviceResource>::Get(browser_context());
399   set_work_thread_id(BrowserThread::FILE);
400   return manager_ != NULL;
401 }
402
403 bool UsbAsyncApiFunction::Respond() {
404   return error_.empty();
405 }
406
407 scoped_refptr<UsbDevice>
408 UsbAsyncApiFunction::GetDeviceOrOrCompleteWithError(
409     const Device& input_device) {
410   if (g_device_for_test)
411     return g_device_for_test;
412
413   const uint16_t vendor_id = input_device.vendor_id;
414   const uint16_t product_id = input_device.product_id;
415   UsbDevicePermission::CheckParam param(
416       vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
417   if (!PermissionsData::CheckAPIPermissionWithParam(
418           GetExtension(), APIPermission::kUsbDevice, &param)) {
419     LOG(WARNING) << "Insufficient permissions to access device.";
420     CompleteWithError(kErrorPermissionDenied);
421     return NULL;
422   }
423
424   UsbService* service = UsbService::GetInstance();
425   if (!service) {
426     CompleteWithError(kErrorInitService);
427     return NULL;
428   }
429   scoped_refptr<UsbDevice> device;
430
431   device = service->GetDeviceById(input_device.device);
432
433   if (!device) {
434     CompleteWithError(kErrorNoDevice);
435     return NULL;
436   }
437
438   if (device->vendor_id() != input_device.vendor_id ||
439       device->product_id() != input_device.product_id) {
440     // Must act as if there is no such a device.
441     // Otherwise can be used to finger print unauthorized devices.
442     CompleteWithError(kErrorNoDevice);
443     return NULL;
444   }
445
446   return device;
447 }
448
449 scoped_refptr<UsbDeviceHandle>
450 UsbAsyncApiFunction::GetDeviceHandleOrCompleteWithError(
451     const ConnectionHandle& input_device_handle) {
452   UsbDeviceResource* resource =
453       manager_->Get(extension_->id(), input_device_handle.handle);
454   if (!resource) {
455     CompleteWithError(kErrorNoDevice);
456     return NULL;
457   }
458
459   if (!resource->device() || !resource->device()->device()) {
460     CompleteWithError(kErrorDisconnect);
461     manager_->Remove(extension_->id(), input_device_handle.handle);
462     return NULL;
463   }
464
465   if (resource->device()->device()->vendor_id() !=
466           input_device_handle.vendor_id ||
467       resource->device()->device()->product_id() !=
468           input_device_handle.product_id) {
469     CompleteWithError(kErrorNoDevice);
470     return NULL;
471   }
472
473   return resource->device();
474 }
475
476 void UsbAsyncApiFunction::RemoveUsbDeviceResource(int api_resource_id) {
477   manager_->Remove(extension_->id(), api_resource_id);
478 }
479
480 void UsbAsyncApiFunction::CompleteWithError(const std::string& error) {
481   SetError(error);
482   AsyncWorkCompleted();
483 }
484
485 UsbAsyncApiTransferFunction::UsbAsyncApiTransferFunction() {}
486
487 UsbAsyncApiTransferFunction::~UsbAsyncApiTransferFunction() {}
488
489 void UsbAsyncApiTransferFunction::OnCompleted(UsbTransferStatus status,
490                                               scoped_refptr<net::IOBuffer> data,
491                                               size_t length) {
492   if (status != USB_TRANSFER_COMPLETED)
493     SetError(ConvertTransferStatusToErrorString(status));
494
495   SetResult(CreateTransferInfo(status, data, length));
496   AsyncWorkCompleted();
497 }
498
499 bool UsbAsyncApiTransferFunction::ConvertDirectionSafely(
500     const Direction& input, UsbEndpointDirection* output) {
501   const bool converted = ConvertDirection(input, output);
502   if (!converted)
503     SetError(kErrorConvertDirection);
504   return converted;
505 }
506
507 bool UsbAsyncApiTransferFunction::ConvertRequestTypeSafely(
508     const RequestType& input, UsbDeviceHandle::TransferRequestType* output) {
509   const bool converted = ConvertRequestType(input, output);
510   if (!converted)
511     SetError(kErrorConvertRequestType);
512   return converted;
513 }
514
515 bool UsbAsyncApiTransferFunction::ConvertRecipientSafely(
516     const Recipient& input, UsbDeviceHandle::TransferRecipient* output) {
517   const bool converted = ConvertRecipient(input, output);
518   if (!converted)
519     SetError(kErrorConvertRecipient);
520   return converted;
521 }
522
523 UsbFindDevicesFunction::UsbFindDevicesFunction() {}
524
525 UsbFindDevicesFunction::~UsbFindDevicesFunction() {}
526
527 bool UsbFindDevicesFunction::Prepare() {
528   parameters_ = FindDevices::Params::Create(*args_);
529   EXTENSION_FUNCTION_VALIDATE(parameters_.get());
530   return true;
531 }
532
533 void UsbFindDevicesFunction::AsyncWorkStart() {
534   scoped_ptr<base::ListValue> result(new base::ListValue());
535
536   if (g_device_for_test) {
537     UsbDeviceResource* const resource = new UsbDeviceResource(
538         extension_->id(),
539         g_device_for_test->Open());
540
541     result->Append(PopulateConnectionHandle(manager_->Add(resource), 0, 0));
542     SetResult(result.release());
543     AsyncWorkCompleted();
544     return;
545   }
546
547   const uint16_t vendor_id = parameters_->options.vendor_id;
548   const uint16_t product_id = parameters_->options.product_id;
549   int interface_id = parameters_->options.interface_id.get() ?
550       *parameters_->options.interface_id.get() :
551       UsbDevicePermissionData::ANY_INTERFACE;
552   UsbDevicePermission::CheckParam param(vendor_id, product_id, interface_id);
553   if (!PermissionsData::CheckAPIPermissionWithParam(
554           GetExtension(), APIPermission::kUsbDevice, &param)) {
555     LOG(WARNING) << "Insufficient permissions to access device.";
556     CompleteWithError(kErrorPermissionDenied);
557     return;
558   }
559
560   UsbService *service = UsbService::GetInstance();
561   if (!service) {
562     CompleteWithError(kErrorInitService);
563     return;
564   }
565
566   ScopedDeviceVector devices(new DeviceVector());
567   service->GetDevices(devices.get());
568
569   for (DeviceVector::iterator it = devices->begin();
570       it != devices->end();) {
571     if ((*it)->vendor_id() != vendor_id || (*it)->product_id() != product_id) {
572       it = devices->erase(it);
573     } else {
574       ++it;
575     }
576   }
577
578 #if defined(OS_CHROMEOS)
579   RequestUsbDevicesAccess(
580       devices.Pass(), interface_id,
581       base::Bind(&UsbFindDevicesFunction::OpenDevices, this));
582 #else
583   OpenDevices(devices.Pass());
584 #endif  // OS_CHROMEOS
585 }
586
587 void UsbFindDevicesFunction::OpenDevices(ScopedDeviceVector devices) {
588   base::ListValue* result = new base::ListValue();
589
590   for (size_t i = 0; i < devices->size(); ++i) {
591     scoped_refptr<UsbDeviceHandle> device_handle =
592       devices->at(i)->Open();
593     if (device_handle)
594       device_handles_.push_back(device_handle);
595   }
596
597   for (size_t i = 0; i < device_handles_.size(); ++i) {
598     UsbDeviceHandle* const device_handle = device_handles_[i].get();
599     UsbDeviceResource* const resource =
600         new UsbDeviceResource(extension_->id(), device_handle);
601
602     result->Append(PopulateConnectionHandle(manager_->Add(resource),
603                                              parameters_->options.vendor_id,
604                                              parameters_->options.product_id));
605   }
606
607   SetResult(result);
608   AsyncWorkCompleted();
609 }
610
611 UsbGetDevicesFunction::UsbGetDevicesFunction() {
612 }
613
614 UsbGetDevicesFunction::~UsbGetDevicesFunction() {
615 }
616
617 void UsbGetDevicesFunction::SetDeviceForTest(UsbDevice* device) {
618   g_device_for_test = device;
619 }
620
621 bool UsbGetDevicesFunction::Prepare() {
622   parameters_ = GetDevices::Params::Create(*args_);
623   EXTENSION_FUNCTION_VALIDATE(parameters_.get());
624   return true;
625 }
626
627 void UsbGetDevicesFunction::AsyncWorkStart() {
628   scoped_ptr<base::ListValue> result(new base::ListValue());
629
630   if (g_device_for_test) {
631     result->Append(PopulateDevice(g_device_for_test));
632     SetResult(result.release());
633     AsyncWorkCompleted();
634     return;
635   }
636
637   const uint16_t vendor_id = parameters_->options.vendor_id;
638   const uint16_t product_id = parameters_->options.product_id;
639   UsbDevicePermission::CheckParam param(
640       vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
641   if (!PermissionsData::CheckAPIPermissionWithParam(
642           GetExtension(), APIPermission::kUsbDevice, &param)) {
643     LOG(WARNING) << "Insufficient permissions to access device.";
644     CompleteWithError(kErrorPermissionDenied);
645     return;
646   }
647
648   UsbService* service = UsbService::GetInstance();
649   if (!service) {
650     CompleteWithError(kErrorInitService);
651     return;
652   }
653
654   DeviceVector devices;
655   service->GetDevices(&devices);
656
657   for (DeviceVector::iterator it = devices.begin(); it != devices.end();) {
658     if ((*it)->vendor_id() != vendor_id || (*it)->product_id() != product_id) {
659       it = devices.erase(it);
660     } else {
661       ++it;
662     }
663   }
664
665   for (size_t i = 0; i < devices.size(); ++i) {
666     result->Append(PopulateDevice(devices[i].get()));
667   }
668
669   SetResult(result.release());
670   AsyncWorkCompleted();
671 }
672
673 UsbRequestAccessFunction::UsbRequestAccessFunction() {}
674
675 UsbRequestAccessFunction::~UsbRequestAccessFunction() {}
676
677 bool UsbRequestAccessFunction::Prepare() {
678   parameters_ = RequestAccess::Params::Create(*args_);
679   EXTENSION_FUNCTION_VALIDATE(parameters_.get());
680   return true;
681 }
682
683 void UsbRequestAccessFunction::AsyncWorkStart() {
684 #if defined(OS_CHROMEOS)
685   scoped_refptr<UsbDevice> device =
686       GetDeviceOrOrCompleteWithError(parameters_->device);
687   if (!device) return;
688
689   device->RequestUsbAcess(parameters_->interface_id,
690                           base::Bind(&UsbRequestAccessFunction::OnCompleted,
691                                      this));
692 #else
693   SetResult(new base::FundamentalValue(false));
694   CompleteWithError(kErrorNotSupported);
695 #endif  // OS_CHROMEOS
696 }
697
698 void UsbRequestAccessFunction::OnCompleted(bool success) {
699   SetResult(new base::FundamentalValue(success));
700   AsyncWorkCompleted();
701 }
702
703 UsbOpenDeviceFunction::UsbOpenDeviceFunction() {}
704
705 UsbOpenDeviceFunction::~UsbOpenDeviceFunction() {}
706
707 bool UsbOpenDeviceFunction::Prepare() {
708   parameters_ = OpenDevice::Params::Create(*args_);
709   EXTENSION_FUNCTION_VALIDATE(parameters_.get());
710   return true;
711 }
712
713 void UsbOpenDeviceFunction::AsyncWorkStart() {
714   scoped_refptr<UsbDevice> device =
715       GetDeviceOrOrCompleteWithError(parameters_->device);
716   if (!device) return;
717
718   handle_ = device->Open();
719   if (!handle_) {
720     SetError(kErrorOpen);
721     AsyncWorkCompleted();
722     return;
723   }
724
725   SetResult(PopulateConnectionHandle(
726       manager_->Add(new UsbDeviceResource(extension_->id(), handle_)),
727       handle_->device()->vendor_id(),
728       handle_->device()->product_id()));
729   AsyncWorkCompleted();
730 }
731
732 UsbListInterfacesFunction::UsbListInterfacesFunction() {}
733
734 UsbListInterfacesFunction::~UsbListInterfacesFunction() {}
735
736 bool UsbListInterfacesFunction::Prepare() {
737   parameters_ = ListInterfaces::Params::Create(*args_);
738   EXTENSION_FUNCTION_VALIDATE(parameters_.get());
739   return true;
740 }
741
742 void UsbListInterfacesFunction::AsyncWorkStart() {
743   scoped_refptr<UsbDeviceHandle> device_handle =
744       GetDeviceHandleOrCompleteWithError(parameters_->handle);
745   if (!device_handle) return;
746
747   scoped_refptr<UsbConfigDescriptor> config =
748       device_handle->device()->ListInterfaces();
749
750   if (!config) {
751     SetError(kErrorCannotListInterfaces);
752     AsyncWorkCompleted();
753     return;
754   }
755
756   result_.reset(new base::ListValue());
757
758   for (size_t i = 0, num_interfaces = config->GetNumInterfaces();
759       i < num_interfaces; ++i) {
760     scoped_refptr<const UsbInterfaceDescriptor>
761         usb_interface(config->GetInterface(i));
762     for (size_t j = 0, num_descriptors = usb_interface->GetNumAltSettings();
763             j < num_descriptors; ++j) {
764       scoped_refptr<const UsbInterfaceAltSettingDescriptor> descriptor
765           = usb_interface->GetAltSetting(j);
766       std::vector<linked_ptr<EndpointDescriptor> > endpoints;
767       for (size_t k = 0, num_endpoints = descriptor->GetNumEndpoints();
768           k < num_endpoints; k++) {
769         scoped_refptr<const UsbEndpointDescriptor> endpoint
770             = descriptor->GetEndpoint(k);
771         linked_ptr<EndpointDescriptor> endpoint_desc(new EndpointDescriptor());
772
773         TransferType type;
774         Direction direction;
775         SynchronizationType synchronization;
776         UsageType usage;
777
778         if (!ConvertTransferTypeSafely(endpoint->GetTransferType(), &type) ||
779             !ConvertDirectionSafely(endpoint->GetDirection(), &direction) ||
780             !ConvertSynchronizationTypeSafely(
781                 endpoint->GetSynchronizationType(), &synchronization) ||
782             !ConvertUsageTypeSafely(endpoint->GetUsageType(), &usage)) {
783           SetError(kErrorCannotListInterfaces);
784           AsyncWorkCompleted();
785           return;
786         }
787
788         endpoint_desc->address = endpoint->GetAddress();
789         endpoint_desc->type = type;
790         endpoint_desc->direction = direction;
791         endpoint_desc->maximum_packet_size = endpoint->GetMaximumPacketSize();
792         endpoint_desc->synchronization = synchronization;
793         endpoint_desc->usage = usage;
794
795         int* polling_interval = new int;
796         endpoint_desc->polling_interval.reset(polling_interval);
797         *polling_interval = endpoint->GetPollingInterval();
798
799         endpoints.push_back(endpoint_desc);
800       }
801
802       result_->Append(PopulateInterfaceDescriptor(
803           descriptor->GetInterfaceNumber(),
804           descriptor->GetAlternateSetting(),
805           descriptor->GetInterfaceClass(),
806           descriptor->GetInterfaceSubclass(),
807           descriptor->GetInterfaceProtocol(),
808           &endpoints));
809     }
810   }
811
812   SetResult(result_.release());
813   AsyncWorkCompleted();
814 }
815
816 bool UsbListInterfacesFunction::ConvertDirectionSafely(
817     const UsbEndpointDirection& input,
818     usb::Direction* output) {
819   const bool converted = ConvertDirectionToApi(input, output);
820   if (!converted)
821     SetError(kErrorConvertDirection);
822   return converted;
823 }
824
825 bool UsbListInterfacesFunction::ConvertSynchronizationTypeSafely(
826     const UsbSynchronizationType& input,
827     usb::SynchronizationType* output) {
828   const bool converted = ConvertSynchronizationTypeToApi(input, output);
829   if (!converted)
830     SetError(kErrorConvertSynchronizationType);
831   return converted;
832 }
833
834 bool UsbListInterfacesFunction::ConvertTransferTypeSafely(
835     const UsbTransferType& input,
836     usb::TransferType* output) {
837   const bool converted = ConvertTransferTypeToApi(input, output);
838   if (!converted)
839     SetError(kErrorConvertTransferType);
840   return converted;
841 }
842
843 bool UsbListInterfacesFunction::ConvertUsageTypeSafely(
844     const UsbUsageType& input,
845     usb::UsageType* output) {
846   const bool converted = ConvertUsageTypeToApi(input, output);
847   if (!converted)
848     SetError(kErrorConvertUsageType);
849   return converted;
850 }
851
852 UsbCloseDeviceFunction::UsbCloseDeviceFunction() {}
853
854 UsbCloseDeviceFunction::~UsbCloseDeviceFunction() {}
855
856 bool UsbCloseDeviceFunction::Prepare() {
857   parameters_ = CloseDevice::Params::Create(*args_);
858   EXTENSION_FUNCTION_VALIDATE(parameters_.get());
859   return true;
860 }
861
862 void UsbCloseDeviceFunction::AsyncWorkStart() {
863   scoped_refptr<UsbDeviceHandle> device_handle =
864       GetDeviceHandleOrCompleteWithError(parameters_->handle);
865   if (!device_handle) return;
866
867   device_handle->Close();
868   RemoveUsbDeviceResource(parameters_->handle.handle);
869   AsyncWorkCompleted();
870 }
871
872 UsbClaimInterfaceFunction::UsbClaimInterfaceFunction() {}
873
874 UsbClaimInterfaceFunction::~UsbClaimInterfaceFunction() {}
875
876 bool UsbClaimInterfaceFunction::Prepare() {
877   parameters_ = ClaimInterface::Params::Create(*args_);
878   EXTENSION_FUNCTION_VALIDATE(parameters_.get());
879   return true;
880 }
881
882 void UsbClaimInterfaceFunction::AsyncWorkStart() {
883   scoped_refptr<UsbDeviceHandle> device_handle =
884       GetDeviceHandleOrCompleteWithError(parameters_->handle);
885   if (!device_handle) return;
886
887   bool success = device_handle->ClaimInterface(parameters_->interface_number);
888
889   if (!success)
890     SetError(kErrorCannotClaimInterface);
891   AsyncWorkCompleted();
892 }
893
894 UsbReleaseInterfaceFunction::UsbReleaseInterfaceFunction() {}
895
896 UsbReleaseInterfaceFunction::~UsbReleaseInterfaceFunction() {}
897
898 bool UsbReleaseInterfaceFunction::Prepare() {
899   parameters_ = ReleaseInterface::Params::Create(*args_);
900   EXTENSION_FUNCTION_VALIDATE(parameters_.get());
901   return true;
902 }
903
904 void UsbReleaseInterfaceFunction::AsyncWorkStart() {
905   scoped_refptr<UsbDeviceHandle> device_handle =
906       GetDeviceHandleOrCompleteWithError(parameters_->handle);
907   if (!device_handle) return;
908
909   bool success = device_handle->ReleaseInterface(parameters_->interface_number);
910   if (!success)
911     SetError(kErrorCannotReleaseInterface);
912   AsyncWorkCompleted();
913 }
914
915 UsbSetInterfaceAlternateSettingFunction::
916     UsbSetInterfaceAlternateSettingFunction() {}
917
918 UsbSetInterfaceAlternateSettingFunction::
919     ~UsbSetInterfaceAlternateSettingFunction() {}
920
921 bool UsbSetInterfaceAlternateSettingFunction::Prepare() {
922   parameters_ = SetInterfaceAlternateSetting::Params::Create(*args_);
923   EXTENSION_FUNCTION_VALIDATE(parameters_.get());
924   return true;
925 }
926
927 void UsbSetInterfaceAlternateSettingFunction::AsyncWorkStart() {
928   scoped_refptr<UsbDeviceHandle> device_handle =
929       GetDeviceHandleOrCompleteWithError(parameters_->handle);
930   if (!device_handle) return;
931
932   bool success = device_handle->SetInterfaceAlternateSetting(
933       parameters_->interface_number,
934       parameters_->alternate_setting);
935   if (!success)
936     SetError(kErrorCannotSetInterfaceAlternateSetting);
937
938   AsyncWorkCompleted();
939 }
940
941 UsbControlTransferFunction::UsbControlTransferFunction() {}
942
943 UsbControlTransferFunction::~UsbControlTransferFunction() {}
944
945 bool UsbControlTransferFunction::Prepare() {
946   parameters_ = ControlTransfer::Params::Create(*args_);
947   EXTENSION_FUNCTION_VALIDATE(parameters_.get());
948   return true;
949 }
950
951 void UsbControlTransferFunction::AsyncWorkStart() {
952   scoped_refptr<UsbDeviceHandle> device_handle =
953       GetDeviceHandleOrCompleteWithError(parameters_->handle);
954   if (!device_handle) return;
955
956   const ControlTransferInfo& transfer = parameters_->transfer_info;
957
958   UsbEndpointDirection direction;
959   UsbDeviceHandle::TransferRequestType request_type;
960   UsbDeviceHandle::TransferRecipient recipient;
961   size_t size = 0;
962
963   if (!ConvertDirectionSafely(transfer.direction, &direction) ||
964       !ConvertRequestTypeSafely(transfer.request_type, &request_type) ||
965       !ConvertRecipientSafely(transfer.recipient, &recipient)) {
966     AsyncWorkCompleted();
967     return;
968   }
969
970   if (!GetTransferSize(transfer, &size)) {
971     CompleteWithError(kErrorInvalidTransferLength);
972     return;
973   }
974
975   scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
976       transfer, direction, size);
977   if (!buffer.get()) {
978     CompleteWithError(kErrorMalformedParameters);
979     return;
980   }
981
982   device_handle->ControlTransfer(
983       direction,
984       request_type,
985       recipient,
986       transfer.request,
987       transfer.value,
988       transfer.index,
989       buffer.get(),
990       size,
991       0,
992       base::Bind(&UsbControlTransferFunction::OnCompleted, this));
993 }
994
995 UsbBulkTransferFunction::UsbBulkTransferFunction() {}
996
997 UsbBulkTransferFunction::~UsbBulkTransferFunction() {}
998
999 bool UsbBulkTransferFunction::Prepare() {
1000   parameters_ = BulkTransfer::Params::Create(*args_);
1001   EXTENSION_FUNCTION_VALIDATE(parameters_.get());
1002   return true;
1003 }
1004
1005 void UsbBulkTransferFunction::AsyncWorkStart() {
1006   scoped_refptr<UsbDeviceHandle> device_handle =
1007       GetDeviceHandleOrCompleteWithError(parameters_->handle);
1008   if (!device_handle) return;
1009
1010   const GenericTransferInfo& transfer = parameters_->transfer_info;
1011
1012   UsbEndpointDirection direction;
1013   size_t size = 0;
1014
1015   if (!ConvertDirectionSafely(transfer.direction, &direction)) {
1016     AsyncWorkCompleted();
1017     return;
1018   }
1019
1020   if (!GetTransferSize(transfer, &size)) {
1021     CompleteWithError(kErrorInvalidTransferLength);
1022     return;
1023   }
1024
1025   scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
1026       transfer, direction, size);
1027   if (!buffer.get()) {
1028     CompleteWithError(kErrorMalformedParameters);
1029     return;
1030   }
1031
1032   device_handle->BulkTransfer(
1033       direction,
1034       transfer.endpoint,
1035       buffer.get(),
1036       size,
1037       0,
1038       base::Bind(&UsbBulkTransferFunction::OnCompleted, this));
1039 }
1040
1041 UsbInterruptTransferFunction::UsbInterruptTransferFunction() {}
1042
1043 UsbInterruptTransferFunction::~UsbInterruptTransferFunction() {}
1044
1045 bool UsbInterruptTransferFunction::Prepare() {
1046   parameters_ = InterruptTransfer::Params::Create(*args_);
1047   EXTENSION_FUNCTION_VALIDATE(parameters_.get());
1048   return true;
1049 }
1050
1051 void UsbInterruptTransferFunction::AsyncWorkStart() {
1052   scoped_refptr<UsbDeviceHandle> device_handle =
1053       GetDeviceHandleOrCompleteWithError(parameters_->handle);
1054   if (!device_handle) return;
1055
1056   const GenericTransferInfo& transfer = parameters_->transfer_info;
1057
1058   UsbEndpointDirection direction;
1059   size_t size = 0;
1060
1061   if (!ConvertDirectionSafely(transfer.direction, &direction)) {
1062     AsyncWorkCompleted();
1063     return;
1064   }
1065
1066   if (!GetTransferSize(transfer, &size)) {
1067     CompleteWithError(kErrorInvalidTransferLength);
1068     return;
1069   }
1070
1071   scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
1072       transfer, direction, size);
1073   if (!buffer.get()) {
1074     CompleteWithError(kErrorMalformedParameters);
1075     return;
1076   }
1077
1078   device_handle->InterruptTransfer(
1079       direction,
1080       transfer.endpoint,
1081       buffer.get(),
1082       size,
1083       0,
1084       base::Bind(&UsbInterruptTransferFunction::OnCompleted, this));
1085 }
1086
1087 UsbIsochronousTransferFunction::UsbIsochronousTransferFunction() {}
1088
1089 UsbIsochronousTransferFunction::~UsbIsochronousTransferFunction() {}
1090
1091 bool UsbIsochronousTransferFunction::Prepare() {
1092   parameters_ = IsochronousTransfer::Params::Create(*args_);
1093   EXTENSION_FUNCTION_VALIDATE(parameters_.get());
1094   return true;
1095 }
1096
1097 void UsbIsochronousTransferFunction::AsyncWorkStart() {
1098   scoped_refptr<UsbDeviceHandle> device_handle =
1099       GetDeviceHandleOrCompleteWithError(parameters_->handle);
1100   if (!device_handle) return;
1101
1102   const IsochronousTransferInfo& transfer = parameters_->transfer_info;
1103   const GenericTransferInfo& generic_transfer = transfer.transfer_info;
1104
1105   size_t size = 0;
1106   UsbEndpointDirection direction;
1107
1108   if (!ConvertDirectionSafely(generic_transfer.direction, &direction)) {
1109     AsyncWorkCompleted();
1110     return;
1111   }
1112   if (!GetTransferSize(generic_transfer, &size)) {
1113     CompleteWithError(kErrorInvalidTransferLength);
1114     return;
1115   }
1116   if (transfer.packets < 0 || transfer.packets >= kMaxPackets) {
1117     CompleteWithError(kErrorInvalidNumberOfPackets);
1118     return;
1119   }
1120   unsigned int packets = transfer.packets;
1121   if (transfer.packet_length < 0 ||
1122       transfer.packet_length >= kMaxPacketLength) {
1123     CompleteWithError(kErrorInvalidPacketLength);
1124     return;
1125   }
1126   unsigned int packet_length = transfer.packet_length;
1127   const uint64 total_length = packets * packet_length;
1128   if (packets > size || total_length > size) {
1129     CompleteWithError(kErrorTransferLength);
1130     return;
1131   }
1132
1133   scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
1134       generic_transfer, direction, size);
1135   if (!buffer.get()) {
1136     CompleteWithError(kErrorMalformedParameters);
1137     return;
1138   }
1139
1140   device_handle->IsochronousTransfer(
1141       direction,
1142       generic_transfer.endpoint,
1143       buffer.get(),
1144       size,
1145       packets,
1146       packet_length,
1147       0,
1148       base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this));
1149 }
1150
1151 UsbResetDeviceFunction::UsbResetDeviceFunction() {}
1152
1153 UsbResetDeviceFunction::~UsbResetDeviceFunction() {}
1154
1155 bool UsbResetDeviceFunction::Prepare() {
1156   parameters_ = ResetDevice::Params::Create(*args_);
1157   EXTENSION_FUNCTION_VALIDATE(parameters_.get());
1158   return true;
1159 }
1160
1161 void UsbResetDeviceFunction::AsyncWorkStart() {
1162   scoped_refptr<UsbDeviceHandle> device_handle =
1163       GetDeviceHandleOrCompleteWithError(parameters_->handle);
1164   if (!device_handle) return;
1165
1166   bool success = device_handle->ResetDevice();
1167   if (!success) {
1168     device_handle->Close();
1169     RemoveUsbDeviceResource(parameters_->handle.handle);
1170     SetResult(new base::FundamentalValue(false));
1171     CompleteWithError(kErrorResetDevice);
1172     return;
1173   }
1174
1175   SetResult(new base::FundamentalValue(true));
1176   AsyncWorkCompleted();
1177 }
1178
1179 }  // namespace extensions