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