1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/browser/api/usb/usb_api.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/core/device_client.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/usb/usb_device_handle.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/usb/usb_service.h"
15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/browser/api/usb/usb_device_resource.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/common/api/usb.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h"
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/common/permissions/usb_device_permission.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace usb = extensions::core_api::usb;
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace BulkTransfer = usb::BulkTransfer;
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace ClaimInterface = usb::ClaimInterface;
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace CloseDevice = usb::CloseDevice;
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace ControlTransfer = usb::ControlTransfer;
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace FindDevices = usb::FindDevices;
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace GetDevices = usb::GetDevices;
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace InterruptTransfer = usb::InterruptTransfer;
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace IsochronousTransfer = usb::IsochronousTransfer;
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace GetConfiguration = usb::GetConfiguration;
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace ListInterfaces = usb::ListInterfaces;
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace OpenDevice = usb::OpenDevice;
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace ReleaseInterface = usb::ReleaseInterface;
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace RequestAccess = usb::RequestAccess;
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace ResetDevice = usb::ResetDevice;
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace SetInterfaceAlternateSetting = usb::SetInterfaceAlternateSetting;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using content::BrowserThread;
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing usb::ConfigDescriptor;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using usb::ControlTransferInfo;
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using usb::ConnectionHandle;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using usb::Device;
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using usb::Direction;
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using usb::EndpointDescriptor;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using usb::GenericTransferInfo;
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using usb::InterfaceDescriptor;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using usb::IsochronousTransferInfo;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using usb::Recipient;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using usb::RequestType;
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using usb::SynchronizationType;
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using usb::TransferType;
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using usb::UsageType;
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbConfigDescriptor;
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbDevice;
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbDeviceFilter;
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbDeviceHandle;
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbEndpointDescriptor;
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbEndpointDirection;
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbInterfaceDescriptor;
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbService;
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbSynchronizationType;
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbTransferStatus;
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbTransferType;
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing device::UsbUsageType;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)typedef std::vector<scoped_refptr<UsbDevice> > DeviceVector;
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)typedef scoped_ptr<DeviceVector> ScopedDeviceVector;
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kDataKey[] = "data";
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kResultCodeKey[] = "resultCode";
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorInitService[] = "Failed to initialize USB service.";
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorOpen[] = "Failed to open device.";
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorCancelled[] = "Transfer was cancelled.";
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorDisconnect[] = "Device disconnected.";
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorGeneric[] = "Transfer failed.";
808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if !defined(OS_CHROMEOS)
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorNotSupported[] = "Not supported on this platform.";
828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorOverflow[] = "Inbound transfer overflow.";
8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorStalled[] = "Transfer stalled.";
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorTimeout[] = "Transfer timed out.";
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorTransferLength[] = "Transfer length is insufficient.";
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorCannotClaimInterface[] = "Error claiming interface.";
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorCannotReleaseInterface[] = "Error releasing interface.";
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorCannotSetInterfaceAlternateSetting[] =
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Error setting alternate interface setting.";
9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorConvertDirection[] = "Invalid transfer direction.";
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorConvertRecipient[] = "Invalid transfer recipient.";
9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorConvertRequestType[] = "Invalid request type.";
9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorMalformedParameters[] = "Error parsing parameters.";
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorNoDevice[] = "No such device.";
96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kErrorPermissionDenied[] = "Permission to access device was denied";
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorInvalidTransferLength[] =
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    "Transfer length must be a positive number less than 104,857,600.";
9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorInvalidNumberOfPackets[] =
10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    "Number of packets must be a positive number less than 4,194,304.";
101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kErrorInvalidPacketLength[] =
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    "Packet length must be a positive number less than 65,536.";
10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kErrorResetDevice[] =
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    "Error resetting the device. The device has been closed.";
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const size_t kMaxTransferLength = 100 * 1024 * 1024;
10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const int kMaxPackets = 4 * 1024 * 1024;
10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const int kMaxPacketLength = 64 * 1024;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ConvertDirectionFromApi(const Direction& input,
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             UsbEndpointDirection* output) {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (input) {
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case usb::DIRECTION_IN:
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      *output = device::USB_DIRECTION_INBOUND;
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case usb::DIRECTION_OUT:
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      *output = device::USB_DIRECTION_OUTBOUND;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      NOTREACHED();
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ConvertRequestTypeFromApi(const RequestType& input,
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               UsbDeviceHandle::TransferRequestType* output) {
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (input) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case usb::REQUEST_TYPE_STANDARD:
129a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      *output = UsbDeviceHandle::STANDARD;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case usb::REQUEST_TYPE_CLASS:
132a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      *output = UsbDeviceHandle::CLASS;
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case usb::REQUEST_TYPE_VENDOR:
135a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      *output = UsbDeviceHandle::VENDOR;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case usb::REQUEST_TYPE_RESERVED:
138a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      *output = UsbDeviceHandle::RESERVED;
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      NOTREACHED();
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ConvertRecipientFromApi(const Recipient& input,
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             UsbDeviceHandle::TransferRecipient* output) {
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (input) {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case usb::RECIPIENT_DEVICE:
150a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      *output = UsbDeviceHandle::DEVICE;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case usb::RECIPIENT_INTERFACE:
153a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      *output = UsbDeviceHandle::INTERFACE;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case usb::RECIPIENT_ENDPOINT:
156a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      *output = UsbDeviceHandle::ENDPOINT;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case usb::RECIPIENT_OTHER:
159a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      *output = UsbDeviceHandle::OTHER;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      NOTREACHED();
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)template <class T>
16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool GetTransferSize(const T& input, size_t* output) {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (input.direction == usb::DIRECTION_IN) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int* length = input.length.get();
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (length && *length >= 0 &&
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        static_cast<size_t>(*length) < kMaxTransferLength) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *output = *length;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (input.direction == usb::DIRECTION_OUT) {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (input.data.get()) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *output = input.data->size();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)template <class T>
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)scoped_refptr<net::IOBuffer> CreateBufferForTransfer(
187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const T& input,
188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    UsbEndpointDirection direction,
189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    size_t size) {
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (size >= kMaxTransferLength)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allocate a |size|-bytes buffer, or a one-byte buffer if |size| is 0. This
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is due to an impedance mismatch between IOBuffer and URBs. An IOBuffer
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cannot represent a zero-length buffer, while an URB can.
196010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buffer =
197010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      new net::IOBuffer(std::max(static_cast<size_t>(1), size));
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (direction == device::USB_DIRECTION_INBOUND) {
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return buffer;
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else if (direction == device::USB_DIRECTION_OUTBOUND) {
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (input.data.get() && size <= input.data->size()) {
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      memcpy(buffer->data(), input.data->data(), size);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return buffer;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTREACHED();
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char* ConvertTransferStatusToApi(const UsbTransferStatus status) {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (status) {
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_TRANSFER_COMPLETED:
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "";
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_TRANSFER_ERROR:
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kErrorGeneric;
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_TRANSFER_TIMEOUT:
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kErrorTimeout;
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_TRANSFER_CANCELLED:
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kErrorCancelled;
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_TRANSFER_STALLED:
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kErrorStalled;
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_TRANSFER_DISCONNECT:
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kErrorDisconnect;
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_TRANSFER_OVERFLOW:
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kErrorOverflow;
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_TRANSFER_LENGTH_SHORT:
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kErrorTransferLength;
22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    default:
23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      NOTREACHED();
23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return "";
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_CHROMEOS)
23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void RequestUsbDevicesAccessHelper(
23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ScopedDeviceVector devices,
23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    std::vector<scoped_refptr<UsbDevice> >::iterator i,
23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int interface_id,
24058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const base::Callback<void(ScopedDeviceVector result)>& callback,
24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool success) {
24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (success) {
24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ++i;
24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else {
24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    i = devices->erase(i);
24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (i == devices->end()) {
24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    callback.Run(devices.Pass());
24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
2516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  (*i)->RequestUsbAccess(interface_id,
2526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                         base::Bind(RequestUsbDevicesAccessHelper,
2536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                    base::Passed(devices.Pass()),
2546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                    i,
2556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                    interface_id,
2566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                    callback));
25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void RequestUsbDevicesAccess(
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ScopedDeviceVector devices,
26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int interface_id,
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const base::Callback<void(ScopedDeviceVector result)>& callback) {
263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (devices->empty()) {
264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    callback.Run(devices.Pass());
265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<scoped_refptr<UsbDevice> >::iterator i = devices->begin();
2686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  (*i)->RequestUsbAccess(interface_id,
2696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                         base::Bind(RequestUsbDevicesAccessHelper,
2706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                    base::Passed(devices.Pass()),
2716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                    i,
2726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                    interface_id,
2736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                    callback));
27458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif  // OS_CHROMEOS
27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
277010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::DictionaryValue* CreateTransferInfo(UsbTransferStatus status,
278010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                          scoped_refptr<net::IOBuffer> data,
279010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                          size_t length) {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::DictionaryValue* result = new base::DictionaryValue();
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->SetInteger(kResultCodeKey, status);
282010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  result->Set(kDataKey,
283010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)              base::BinaryValue::CreateWithCopiedBuffer(data->data(), length));
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
287010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::Value* PopulateConnectionHandle(int handle,
288010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                      int vendor_id,
28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                      int product_id) {
29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ConnectionHandle result;
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  result.handle = handle;
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  result.vendor_id = vendor_id;
29358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  result.product_id = product_id;
29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return result.ToValue().release();
29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)base::Value* PopulateDevice(UsbDevice* device) {
29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Device result;
29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  result.device = device->unique_id();
30058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  result.vendor_id = device->vendor_id();
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  result.product_id = device->product_id();
30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return result.ToValue().release();
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTransferType ConvertTransferTypeToApi(const UsbTransferType& input) {
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  switch (input) {
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_TRANSFER_CONTROL:
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::TRANSFER_TYPE_CONTROL;
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_TRANSFER_INTERRUPT:
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::TRANSFER_TYPE_INTERRUPT;
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_TRANSFER_ISOCHRONOUS:
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::TRANSFER_TYPE_ISOCHRONOUS;
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_TRANSFER_BULK:
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::TRANSFER_TYPE_BULK;
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    default:
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      NOTREACHED();
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::TRANSFER_TYPE_NONE;
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciDirection ConvertDirectionToApi(const UsbEndpointDirection& input) {
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  switch (input) {
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_DIRECTION_INBOUND:
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::DIRECTION_IN;
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_DIRECTION_OUTBOUND:
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::DIRECTION_OUT;
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    default:
3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      NOTREACHED();
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::DIRECTION_NONE;
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciSynchronizationType ConvertSynchronizationTypeToApi(
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const UsbSynchronizationType& input) {
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  switch (input) {
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_SYNCHRONIZATION_NONE:
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::SYNCHRONIZATION_TYPE_NONE;
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_SYNCHRONIZATION_ASYNCHRONOUS:
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::SYNCHRONIZATION_TYPE_ASYNCHRONOUS;
3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_SYNCHRONIZATION_ADAPTIVE:
3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::SYNCHRONIZATION_TYPE_ADAPTIVE;
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_SYNCHRONIZATION_SYNCHRONOUS:
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::SYNCHRONIZATION_TYPE_SYNCHRONOUS;
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    default:
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      NOTREACHED();
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::SYNCHRONIZATION_TYPE_NONE;
3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciUsageType ConvertUsageTypeToApi(const UsbUsageType& input) {
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  switch (input) {
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_USAGE_DATA:
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::USAGE_TYPE_DATA;
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_USAGE_FEEDBACK:
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::USAGE_TYPE_FEEDBACK;
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case device::USB_USAGE_EXPLICIT_FEEDBACK:
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::USAGE_TYPE_EXPLICITFEEDBACK;
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    default:
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      NOTREACHED();
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return usb::USAGE_TYPE_NONE;
3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ConvertEndpointDescriptor(const UsbEndpointDescriptor& input,
3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               EndpointDescriptor* output) {
3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->address = input.address;
3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->type = ConvertTransferTypeToApi(input.transfer_type);
3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->direction = ConvertDirectionToApi(input.direction);
3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->maximum_packet_size = input.maximum_packet_size;
3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->synchronization =
3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ConvertSynchronizationTypeToApi(input.synchronization_type);
3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->usage = ConvertUsageTypeToApi(input.usage_type);
3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->polling_interval.reset(new int(input.polling_interval));
3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (input.extra_data.size() > 0) {
3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    output->extra_data =
3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        std::string(reinterpret_cast<const char*>(&input.extra_data[0]),
3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    input.extra_data.size());
3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ConvertInterfaceDescriptor(const UsbInterfaceDescriptor& input,
3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                InterfaceDescriptor* output) {
3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->interface_number = input.interface_number;
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->alternate_setting = input.alternate_setting;
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->interface_class = input.interface_class;
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->interface_subclass = input.interface_subclass;
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->interface_protocol = input.interface_protocol;
3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (UsbEndpointDescriptor::Iterator endpointIt = input.endpoints.begin();
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       endpointIt != input.endpoints.end();
3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       ++endpointIt) {
3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    linked_ptr<EndpointDescriptor> endpoint(new EndpointDescriptor);
3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ConvertEndpointDescriptor(*endpointIt, endpoint.get());
3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    output->endpoints.push_back(endpoint);
3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (input.extra_data.size() > 0) {
3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    output->extra_data =
3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        std::string(reinterpret_cast<const char*>(&input.extra_data[0]),
3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    input.extra_data.size());
3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ConvertConfigDescriptor(const UsbConfigDescriptor& input,
4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             ConfigDescriptor* output) {
4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->configuration_value = input.configuration_value;
4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->self_powered = input.self_powered;
4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->remote_wakeup = input.remote_wakeup;
4071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  output->max_power = input.maximum_power;
4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (UsbInterfaceDescriptor::Iterator interfaceIt = input.interfaces.begin();
4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       interfaceIt != input.interfaces.end();
4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       ++interfaceIt) {
4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    linked_ptr<InterfaceDescriptor> interface(new InterfaceDescriptor);
4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ConvertInterfaceDescriptor(*interfaceIt, interface.get());
4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    output->interfaces.push_back(interface);
4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (input.extra_data.size() > 0) {
4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    output->extra_data =
4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        std::string(reinterpret_cast<const char*>(&input.extra_data[0]),
4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    input.extra_data.size());
4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
42090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
42190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
426010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbAsyncApiFunction::UsbAsyncApiFunction() : manager_(NULL) {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UsbAsyncApiFunction::~UsbAsyncApiFunction() {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UsbAsyncApiFunction::PrePrepare() {
433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  manager_ = ApiResourceManager<UsbDeviceResource>::Get(browser_context());
434424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  set_work_thread_id(BrowserThread::FILE);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return manager_ != NULL;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UsbAsyncApiFunction::Respond() {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return error_.empty();
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid UsbAsyncApiFunction::CreateDeviceFilter(const usb::DeviceFilter& input,
4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                             UsbDeviceFilter* output) {
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (input.vendor_id) {
4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    output->SetVendorId(*input.vendor_id);
4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (input.product_id) {
4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    output->SetProductId(*input.product_id);
4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (input.interface_class) {
4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    output->SetInterfaceClass(*input.interface_class);
45358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (input.interface_subclass) {
4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    output->SetInterfaceSubclass(*input.interface_subclass);
4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (input.interface_protocol) {
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    output->SetInterfaceProtocol(*input.interface_protocol);
4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
46158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool UsbAsyncApiFunction::HasDevicePermission(scoped_refptr<UsbDevice> device) {
4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UsbDevicePermission::CheckParam param(
4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      device->vendor_id(),
4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      device->product_id(),
4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
4671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return extension()->permissions_data()->CheckAPIPermissionWithParam(
4681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      APIPermission::kUsbDevice, &param);
4691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_refptr<UsbDevice> UsbAsyncApiFunction::GetDeviceOrCompleteWithError(
4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const Device& input_device) {
4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UsbService* service = device::DeviceClient::Get()->GetUsbService();
47458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!service) {
47558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    CompleteWithError(kErrorInitService);
47658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return NULL;
47758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
47858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<UsbDevice> device = service->GetDeviceById(input_device.device);
4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device.get()) {
48158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    CompleteWithError(kErrorNoDevice);
48258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return NULL;
48358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
48458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!HasDevicePermission(device)) {
48658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Must act as if there is no such a device.
48758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Otherwise can be used to finger print unauthorized devices.
48858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    CompleteWithError(kErrorNoDevice);
48958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return NULL;
49058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
49158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
49258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return device;
49358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
49458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
49558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)scoped_refptr<UsbDeviceHandle>
49658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)UsbAsyncApiFunction::GetDeviceHandleOrCompleteWithError(
49758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const ConnectionHandle& input_device_handle) {
49858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  UsbDeviceResource* resource =
49958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      manager_->Get(extension_->id(), input_device_handle.handle);
50058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!resource) {
50158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    CompleteWithError(kErrorNoDevice);
50258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return NULL;
50358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!resource->device().get() || !resource->device()->GetDevice().get()) {
5061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CompleteWithError(kErrorDisconnect);
5071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    manager_->Remove(extension_->id(), input_device_handle.handle);
5081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return NULL;
5091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
5101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
511cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (resource->device()->GetDevice()->vendor_id() !=
51258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          input_device_handle.vendor_id ||
513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      resource->device()->GetDevice()->product_id() !=
51458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          input_device_handle.product_id) {
51558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    CompleteWithError(kErrorNoDevice);
51658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return NULL;
51758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
51858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
51958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return resource->device();
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UsbAsyncApiFunction::RemoveUsbDeviceResource(int api_resource_id) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager_->Remove(extension_->id(), api_resource_id);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UsbAsyncApiFunction::CompleteWithError(const std::string& error) {
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetError(error);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AsyncWorkCompleted();
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
531010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbAsyncApiTransferFunction::UsbAsyncApiTransferFunction() {
532010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
534010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbAsyncApiTransferFunction::~UsbAsyncApiTransferFunction() {
535010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UsbAsyncApiTransferFunction::OnCompleted(UsbTransferStatus status,
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              scoped_refptr<net::IOBuffer> data,
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              size_t length) {
5401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (status != device::USB_TRANSFER_COMPLETED)
5411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SetError(ConvertTransferStatusToApi(status));
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetResult(CreateTransferInfo(status, data, length));
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AsyncWorkCompleted();
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UsbAsyncApiTransferFunction::ConvertDirectionSafely(
548010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const Direction& input,
549010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    UsbEndpointDirection* output) {
5501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const bool converted = ConvertDirectionFromApi(input, output);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!converted)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetError(kErrorConvertDirection);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return converted;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UsbAsyncApiTransferFunction::ConvertRequestTypeSafely(
557010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const RequestType& input,
558010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    UsbDeviceHandle::TransferRequestType* output) {
5591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const bool converted = ConvertRequestTypeFromApi(input, output);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!converted)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetError(kErrorConvertRequestType);
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return converted;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UsbAsyncApiTransferFunction::ConvertRecipientSafely(
566010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const Recipient& input,
567010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    UsbDeviceHandle::TransferRecipient* output) {
5681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const bool converted = ConvertRecipientFromApi(input, output);
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!converted)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetError(kErrorConvertRecipient);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return converted;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
574010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbFindDevicesFunction::UsbFindDevicesFunction() {
575010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
577010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbFindDevicesFunction::~UsbFindDevicesFunction() {
578010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UsbFindDevicesFunction::Prepare() {
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parameters_ = FindDevices::Params::Create(*args_);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UsbFindDevicesFunction::AsyncWorkStart() {
58758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<base::ListValue> result(new base::ListValue());
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint16_t vendor_id = parameters_->options.vendor_id;
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint16_t product_id = parameters_->options.product_id;
590010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int interface_id = parameters_->options.interface_id.get()
591010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                         ? *parameters_->options.interface_id.get()
592010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                         : UsbDevicePermissionData::ANY_INTERFACE;
593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  UsbDevicePermission::CheckParam param(vendor_id, product_id, interface_id);
5945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!extension()->permissions_data()->CheckAPIPermissionWithParam(
59546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          APIPermission::kUsbDevice, &param)) {
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(WARNING) << "Insufficient permissions to access device.";
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompleteWithError(kErrorPermissionDenied);
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UsbService* service = device::DeviceClient::Get()->GetUsbService();
60258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!service) {
60358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    CompleteWithError(kErrorInitService);
60458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
60558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
60658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
60758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ScopedDeviceVector devices(new DeviceVector());
60858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  service->GetDevices(devices.get());
60958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
610010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (DeviceVector::iterator it = devices->begin(); it != devices->end();) {
61158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if ((*it)->vendor_id() != vendor_id || (*it)->product_id() != product_id) {
61258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      it = devices->erase(it);
61358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    } else {
61458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ++it;
61558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
61658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
61758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
61858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_CHROMEOS)
61958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RequestUsbDevicesAccess(
620010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      devices.Pass(),
621010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      interface_id,
62258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&UsbFindDevicesFunction::OpenDevices, this));
62358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#else
62458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OpenDevices(devices.Pass());
62558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif  // OS_CHROMEOS
626a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
627a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
62858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void UsbFindDevicesFunction::OpenDevices(ScopedDeviceVector devices) {
62958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::ListValue* result = new base::ListValue();
63058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
631ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  for (size_t i = 0; i < devices->size(); ++i) {
632010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_refptr<UsbDeviceHandle> device_handle = devices->at(i)->Open();
6331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (device_handle.get())
634ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      device_handles_.push_back(device_handle);
635ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
636ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
637ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  for (size_t i = 0; i < device_handles_.size(); ++i) {
638ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    UsbDeviceHandle* const device_handle = device_handles_[i].get();
639868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    UsbDeviceResource* const resource =
640ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        new UsbDeviceResource(extension_->id(), device_handle);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    result->Append(PopulateConnectionHandle(manager_->Add(resource),
643010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                            parameters_->options.vendor_id,
644010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                            parameters_->options.product_id));
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetResult(result);
64858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  AsyncWorkCompleted();
64958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
65058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
65158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)UsbGetDevicesFunction::UsbGetDevicesFunction() {
65258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
65358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
65458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)UsbGetDevicesFunction::~UsbGetDevicesFunction() {
65558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
65658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
65758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool UsbGetDevicesFunction::Prepare() {
65858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  parameters_ = GetDevices::Params::Create(*args_);
65958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
66058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
66158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
66258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
66358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void UsbGetDevicesFunction::AsyncWorkStart() {
6641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<UsbDeviceFilter> filters;
6651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (parameters_->options.filters) {
6661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    filters.resize(parameters_->options.filters->size());
6671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (size_t i = 0; i < parameters_->options.filters->size(); ++i) {
6681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      CreateDeviceFilter(*parameters_->options.filters->at(i).get(),
6691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         &filters[i]);
6701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
6711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
6721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (parameters_->options.vendor_id) {
6731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    filters.resize(filters.size() + 1);
6741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    filters.back().SetVendorId(*parameters_->options.vendor_id);
6751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (parameters_->options.product_id) {
6761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      filters.back().SetProductId(*parameters_->options.product_id);
6771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
67858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
67958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UsbService* service = device::DeviceClient::Get()->GetUsbService();
68158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!service) {
68258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    CompleteWithError(kErrorInitService);
68358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
68458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
68558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
68658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DeviceVector devices;
68758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  service->GetDevices(&devices);
68858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::ListValue> result(new base::ListValue());
6901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (DeviceVector::iterator it = devices.begin(); it != devices.end(); ++it) {
6911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_refptr<UsbDevice> device = *it;
6921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if ((filters.empty() || UsbDeviceFilter::MatchesAny(device, filters)) &&
6931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        HasDevicePermission(device)) {
6941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      result->Append(PopulateDevice(it->get()));
69558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
69658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
69758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
69858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetResult(result.release());
69958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  AsyncWorkCompleted();
70058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
70158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
702010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbRequestAccessFunction::UsbRequestAccessFunction() {
703010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
70458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
705010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbRequestAccessFunction::~UsbRequestAccessFunction() {
706010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
70758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
70858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool UsbRequestAccessFunction::Prepare() {
70958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  parameters_ = RequestAccess::Params::Create(*args_);
71058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
71158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
71258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
71358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
71458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void UsbRequestAccessFunction::AsyncWorkStart() {
71558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_CHROMEOS)
71658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<UsbDevice> device =
7171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetDeviceOrCompleteWithError(parameters_->device);
7181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device.get())
719010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
72058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  device->RequestUsbAccess(
722010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      parameters_->interface_id,
723010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::Bind(&UsbRequestAccessFunction::OnCompleted, this));
72458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#else
72558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetResult(new base::FundamentalValue(false));
72658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  CompleteWithError(kErrorNotSupported);
72758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif  // OS_CHROMEOS
72858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
72958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
73058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void UsbRequestAccessFunction::OnCompleted(bool success) {
73158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetResult(new base::FundamentalValue(success));
73258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  AsyncWorkCompleted();
73358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
73458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
735010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbOpenDeviceFunction::UsbOpenDeviceFunction() {
736010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
73758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
738010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbOpenDeviceFunction::~UsbOpenDeviceFunction() {
739010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
74058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
74158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool UsbOpenDeviceFunction::Prepare() {
74258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  parameters_ = OpenDevice::Params::Create(*args_);
74358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
74458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
74558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
74658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
74758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void UsbOpenDeviceFunction::AsyncWorkStart() {
74858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<UsbDevice> device =
7491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetDeviceOrCompleteWithError(parameters_->device);
7501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device.get())
751010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
75258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
75358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  handle_ = device->Open();
7541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!handle_.get()) {
75558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    SetError(kErrorOpen);
75658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    AsyncWorkCompleted();
75758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
75858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
75958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
76058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetResult(PopulateConnectionHandle(
76158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      manager_->Add(new UsbDeviceResource(extension_->id(), handle_)),
762cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      handle_->GetDevice()->vendor_id(),
763cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      handle_->GetDevice()->product_id()));
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AsyncWorkCompleted();
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciUsbGetConfigurationFunction::UsbGetConfigurationFunction() {
768010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
76990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciUsbGetConfigurationFunction::~UsbGetConfigurationFunction() {
771010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
77290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool UsbGetConfigurationFunction::Prepare() {
7741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  parameters_ = GetConfiguration::Params::Create(*args_);
77590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
77690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return true;
77790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
77890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid UsbGetConfigurationFunction::AsyncWorkStart() {
78058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<UsbDeviceHandle> device_handle =
78158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      GetDeviceHandleOrCompleteWithError(parameters_->handle);
7821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device_handle.get()) {
78390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
78490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
78590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ConfigDescriptor config;
7871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ConvertConfigDescriptor(device_handle->GetDevice()->GetConfiguration(),
7881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          &config);
78990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetResult(config.ToValue().release());
79190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  AsyncWorkCompleted();
79290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
79390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciUsbListInterfacesFunction::UsbListInterfacesFunction() {
79590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
79690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciUsbListInterfacesFunction::~UsbListInterfacesFunction() {
79890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
79990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool UsbListInterfacesFunction::Prepare() {
8011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  parameters_ = ListInterfaces::Params::Create(*args_);
8021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
8031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
80490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
80590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid UsbListInterfacesFunction::AsyncWorkStart() {
8071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<UsbDeviceHandle> device_handle =
8081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetDeviceHandleOrCompleteWithError(parameters_->handle);
8091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device_handle.get()) {
8101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
8111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
8121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
8131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ConfigDescriptor config;
8141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ConvertConfigDescriptor(device_handle->GetDevice()->GetConfiguration(),
8151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          &config);
8161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
8171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::ListValue> result(new base::ListValue);
8181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < config.interfaces.size(); ++i) {
8191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    result->Append(config.interfaces[i]->ToValue().release());
8201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
8211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
8221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetResult(result.release());
8231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AsyncWorkCompleted();
82490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
82590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
826010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbCloseDeviceFunction::UsbCloseDeviceFunction() {
827010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
829010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbCloseDeviceFunction::~UsbCloseDeviceFunction() {
830010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UsbCloseDeviceFunction::Prepare() {
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parameters_ = CloseDevice::Params::Create(*args_);
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UsbCloseDeviceFunction::AsyncWorkStart() {
83958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<UsbDeviceHandle> device_handle =
84058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      GetDeviceHandleOrCompleteWithError(parameters_->handle);
8411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device_handle.get())
842010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  device_handle->Close();
84558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RemoveUsbDeviceResource(parameters_->handle.handle);
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AsyncWorkCompleted();
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
849010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbClaimInterfaceFunction::UsbClaimInterfaceFunction() {
850010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
852010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbClaimInterfaceFunction::~UsbClaimInterfaceFunction() {
853010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UsbClaimInterfaceFunction::Prepare() {
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parameters_ = ClaimInterface::Params::Create(*args_);
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UsbClaimInterfaceFunction::AsyncWorkStart() {
86258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<UsbDeviceHandle> device_handle =
86358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      GetDeviceHandleOrCompleteWithError(parameters_->handle);
8641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device_handle.get())
865010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool success = device_handle->ClaimInterface(parameters_->interface_number);
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!success)
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetError(kErrorCannotClaimInterface);
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AsyncWorkCompleted();
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
874010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbReleaseInterfaceFunction::UsbReleaseInterfaceFunction() {
875010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
877010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbReleaseInterfaceFunction::~UsbReleaseInterfaceFunction() {
878010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UsbReleaseInterfaceFunction::Prepare() {
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parameters_ = ReleaseInterface::Params::Create(*args_);
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UsbReleaseInterfaceFunction::AsyncWorkStart() {
88758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<UsbDeviceHandle> device_handle =
88858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      GetDeviceHandleOrCompleteWithError(parameters_->handle);
8891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device_handle.get())
890010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
89158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
89258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool success = device_handle->ReleaseInterface(parameters_->interface_number);
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!success)
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetError(kErrorCannotReleaseInterface);
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AsyncWorkCompleted();
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UsbSetInterfaceAlternateSettingFunction::
899010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    UsbSetInterfaceAlternateSettingFunction() {
900010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UsbSetInterfaceAlternateSettingFunction::
903010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ~UsbSetInterfaceAlternateSettingFunction() {
904010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UsbSetInterfaceAlternateSettingFunction::Prepare() {
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parameters_ = SetInterfaceAlternateSetting::Params::Create(*args_);
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UsbSetInterfaceAlternateSettingFunction::AsyncWorkStart() {
91358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<UsbDeviceHandle> device_handle =
91458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      GetDeviceHandleOrCompleteWithError(parameters_->handle);
9151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device_handle.get())
916010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool success = device_handle->SetInterfaceAlternateSetting(
919010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      parameters_->interface_number, parameters_->alternate_setting);
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!success)
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetError(kErrorCannotSetInterfaceAlternateSetting);
922424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AsyncWorkCompleted();
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
926010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbControlTransferFunction::UsbControlTransferFunction() {
927010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
929010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbControlTransferFunction::~UsbControlTransferFunction() {
930010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UsbControlTransferFunction::Prepare() {
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parameters_ = ControlTransfer::Params::Create(*args_);
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UsbControlTransferFunction::AsyncWorkStart() {
93958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<UsbDeviceHandle> device_handle =
94058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      GetDeviceHandleOrCompleteWithError(parameters_->handle);
9411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device_handle.get())
942010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ControlTransferInfo& transfer = parameters_->transfer_info;
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UsbEndpointDirection direction;
947a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  UsbDeviceHandle::TransferRequestType request_type;
948a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  UsbDeviceHandle::TransferRecipient recipient;
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t size = 0;
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ConvertDirectionSafely(transfer.direction, &direction) ||
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !ConvertRequestTypeSafely(transfer.request_type, &request_type) ||
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !ConvertRecipientSafely(transfer.recipient, &recipient)) {
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AsyncWorkCompleted();
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetTransferSize(transfer, &size)) {
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompleteWithError(kErrorInvalidTransferLength);
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
963010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buffer =
964010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      CreateBufferForTransfer(transfer, direction, size);
965868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!buffer.get()) {
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CompleteWithError(kErrorMalformedParameters);
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  device_handle->ControlTransfer(
971868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      direction,
972868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      request_type,
973868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      recipient,
974868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      transfer.request,
975868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      transfer.value,
976868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      transfer.index,
977868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      buffer.get(),
978868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      size,
979868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      0,
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&UsbControlTransferFunction::OnCompleted, this));
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
983010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbBulkTransferFunction::UsbBulkTransferFunction() {
984010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
986010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbBulkTransferFunction::~UsbBulkTransferFunction() {
987010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UsbBulkTransferFunction::Prepare() {
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parameters_ = BulkTransfer::Params::Create(*args_);
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UsbBulkTransferFunction::AsyncWorkStart() {
99658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<UsbDeviceHandle> device_handle =
99758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      GetDeviceHandleOrCompleteWithError(parameters_->handle);
9981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device_handle.get())
999010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GenericTransferInfo& transfer = parameters_->transfer_info;
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UsbEndpointDirection direction;
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t size = 0;
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ConvertDirectionSafely(transfer.direction, &direction)) {
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AsyncWorkCompleted();
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetTransferSize(transfer, &size)) {
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompleteWithError(kErrorInvalidTransferLength);
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1016010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buffer =
1017010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      CreateBufferForTransfer(transfer, direction, size);
1018868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!buffer.get()) {
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CompleteWithError(kErrorMalformedParameters);
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  device_handle->BulkTransfer(
102458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      direction,
102558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      transfer.endpoint,
102658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      buffer.get(),
102758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      size,
102858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      0,
102958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&UsbBulkTransferFunction::OnCompleted, this));
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1032010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbInterruptTransferFunction::UsbInterruptTransferFunction() {
1033010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbInterruptTransferFunction::~UsbInterruptTransferFunction() {
1036010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UsbInterruptTransferFunction::Prepare() {
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parameters_ = InterruptTransfer::Params::Create(*args_);
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UsbInterruptTransferFunction::AsyncWorkStart() {
104558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<UsbDeviceHandle> device_handle =
104658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      GetDeviceHandleOrCompleteWithError(parameters_->handle);
10471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device_handle.get())
1048010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GenericTransferInfo& transfer = parameters_->transfer_info;
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UsbEndpointDirection direction;
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t size = 0;
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ConvertDirectionSafely(transfer.direction, &direction)) {
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AsyncWorkCompleted();
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetTransferSize(transfer, &size)) {
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompleteWithError(kErrorInvalidTransferLength);
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1065010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buffer =
1066010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      CreateBufferForTransfer(transfer, direction, size);
1067868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!buffer.get()) {
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CompleteWithError(kErrorMalformedParameters);
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  device_handle->InterruptTransfer(
1073868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      direction,
1074868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      transfer.endpoint,
1075868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      buffer.get(),
1076868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      size,
1077868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      0,
1078868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&UsbInterruptTransferFunction::OnCompleted, this));
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1081010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbIsochronousTransferFunction::UsbIsochronousTransferFunction() {
1082010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1084010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbIsochronousTransferFunction::~UsbIsochronousTransferFunction() {
1085010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UsbIsochronousTransferFunction::Prepare() {
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parameters_ = IsochronousTransfer::Params::Create(*args_);
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UsbIsochronousTransferFunction::AsyncWorkStart() {
109458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<UsbDeviceHandle> device_handle =
109558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      GetDeviceHandleOrCompleteWithError(parameters_->handle);
10961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device_handle.get())
1097010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const IsochronousTransferInfo& transfer = parameters_->transfer_info;
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GenericTransferInfo& generic_transfer = transfer.transfer_info;
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t size = 0;
110390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UsbEndpointDirection direction;
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ConvertDirectionSafely(generic_transfer.direction, &direction)) {
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AsyncWorkCompleted();
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetTransferSize(generic_transfer, &size)) {
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompleteWithError(kErrorInvalidTransferLength);
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (transfer.packets < 0 || transfer.packets >= kMaxPackets) {
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompleteWithError(kErrorInvalidNumberOfPackets);
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned int packets = transfer.packets;
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (transfer.packet_length < 0 ||
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      transfer.packet_length >= kMaxPacketLength) {
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompleteWithError(kErrorInvalidPacketLength);
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned int packet_length = transfer.packet_length;
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint64 total_length = packets * packet_length;
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (packets > size || total_length > size) {
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompleteWithError(kErrorTransferLength);
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buffer =
1131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      CreateBufferForTransfer(generic_transfer, direction, size);
1132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!buffer.get()) {
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompleteWithError(kErrorMalformedParameters);
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  device_handle->IsochronousTransfer(
1138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      direction,
1139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      generic_transfer.endpoint,
1140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      buffer.get(),
1141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      size,
1142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      packets,
1143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      packet_length,
1144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      0,
1145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this));
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbResetDeviceFunction::UsbResetDeviceFunction() {
1149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
1150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)UsbResetDeviceFunction::~UsbResetDeviceFunction() {
1152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
1153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool UsbResetDeviceFunction::Prepare() {
1155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  parameters_ = ResetDevice::Params::Create(*args_);
1156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
1157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
1158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void UsbResetDeviceFunction::AsyncWorkStart() {
116158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<UsbDeviceHandle> device_handle =
116258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      GetDeviceHandleOrCompleteWithError(parameters_->handle);
11631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device_handle.get())
1164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
1165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
116658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool success = device_handle->ResetDevice();
1167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!success) {
116858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    device_handle->Close();
116958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    RemoveUsbDeviceResource(parameters_->handle.handle);
1170424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    SetResult(new base::FundamentalValue(false));
117158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    CompleteWithError(kErrorResetDevice);
1172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
1173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
117458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SetResult(new base::FundamentalValue(true));
1176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AsyncWorkCompleted();
1177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
1180