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