1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/browser/api/usb/usb_api.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "components/usb_service/usb_device_handle.h"
13 #include "components/usb_service/usb_service.h"
14 #include "extensions/browser/api/usb/usb_device_resource.h"
15 #include "extensions/browser/extension_system.h"
16 #include "extensions/common/api/usb.h"
17 #include "extensions/common/permissions/permissions_data.h"
18 #include "extensions/common/permissions/usb_device_permission.h"
20 namespace usb
= extensions::core_api::usb
;
21 namespace BulkTransfer
= usb::BulkTransfer
;
22 namespace ClaimInterface
= usb::ClaimInterface
;
23 namespace CloseDevice
= usb::CloseDevice
;
24 namespace ControlTransfer
= usb::ControlTransfer
;
25 namespace FindDevices
= usb::FindDevices
;
26 namespace GetDevices
= usb::GetDevices
;
27 namespace InterruptTransfer
= usb::InterruptTransfer
;
28 namespace IsochronousTransfer
= usb::IsochronousTransfer
;
29 namespace ListInterfaces
= usb::ListInterfaces
;
30 namespace OpenDevice
= usb::OpenDevice
;
31 namespace ReleaseInterface
= usb::ReleaseInterface
;
32 namespace RequestAccess
= usb::RequestAccess
;
33 namespace ResetDevice
= usb::ResetDevice
;
34 namespace SetInterfaceAlternateSetting
= usb::SetInterfaceAlternateSetting
;
36 using content::BrowserThread
;
39 using usb::ControlTransferInfo
;
40 using usb::ConnectionHandle
;
43 using usb::EndpointDescriptor
;
44 using usb::GenericTransferInfo
;
45 using usb::InterfaceDescriptor
;
46 using usb::IsochronousTransferInfo
;
48 using usb::RequestType
;
49 using usb::SynchronizationType
;
50 using usb::TransferType
;
52 using usb_service::UsbConfigDescriptor
;
53 using usb_service::UsbDevice
;
54 using usb_service::UsbDeviceHandle
;
55 using usb_service::UsbEndpointDescriptor
;
56 using usb_service::UsbEndpointDirection
;
57 using usb_service::UsbInterfaceAltSettingDescriptor
;
58 using usb_service::UsbInterfaceDescriptor
;
59 using usb_service::UsbService
;
60 using usb_service::UsbSynchronizationType
;
61 using usb_service::UsbTransferStatus
;
62 using usb_service::UsbTransferType
;
63 using usb_service::UsbUsageType
;
65 typedef std::vector
<scoped_refptr
<UsbDevice
> > DeviceVector
;
66 typedef scoped_ptr
<DeviceVector
> ScopedDeviceVector
;
70 const char kDataKey
[] = "data";
71 const char kResultCodeKey
[] = "resultCode";
73 const char kErrorInitService
[] = "Failed to initialize USB service.";
75 const char kErrorOpen
[] = "Failed to open device.";
76 const char kErrorCancelled
[] = "Transfer was cancelled.";
77 const char kErrorDisconnect
[] = "Device disconnected.";
78 const char kErrorGeneric
[] = "Transfer failed.";
79 #if !defined(OS_CHROMEOS)
80 const char kErrorNotSupported
[] = "Not supported on this platform.";
82 const char kErrorOverflow
[] = "Inbound transfer overflow.";
83 const char kErrorStalled
[] = "Transfer stalled.";
84 const char kErrorTimeout
[] = "Transfer timed out.";
85 const char kErrorTransferLength
[] = "Transfer length is insufficient.";
87 const char kErrorCannotListInterfaces
[] = "Error listing interfaces.";
88 const char kErrorCannotClaimInterface
[] = "Error claiming interface.";
89 const char kErrorCannotReleaseInterface
[] = "Error releasing interface.";
90 const char kErrorCannotSetInterfaceAlternateSetting
[] =
91 "Error setting alternate interface setting.";
92 const char kErrorConvertDirection
[] = "Invalid transfer direction.";
93 const char kErrorConvertRecipient
[] = "Invalid transfer recipient.";
94 const char kErrorConvertRequestType
[] = "Invalid request type.";
95 const char kErrorConvertSynchronizationType
[] = "Invalid synchronization type";
96 const char kErrorConvertTransferType
[] = "Invalid endpoint type.";
97 const char kErrorConvertUsageType
[] = "Invalid usage type.";
98 const char kErrorMalformedParameters
[] = "Error parsing parameters.";
99 const char kErrorNoDevice
[] = "No such device.";
100 const char kErrorPermissionDenied
[] = "Permission to access device was denied";
101 const char kErrorInvalidTransferLength
[] =
102 "Transfer length must be a positive number less than 104,857,600.";
103 const char kErrorInvalidNumberOfPackets
[] =
104 "Number of packets must be a positive number less than 4,194,304.";
105 const char kErrorInvalidPacketLength
[] =
106 "Packet length must be a positive number less than 65,536.";
107 const char kErrorResetDevice
[] =
108 "Error resetting the device. The device has been closed.";
110 const size_t kMaxTransferLength
= 100 * 1024 * 1024;
111 const int kMaxPackets
= 4 * 1024 * 1024;
112 const int kMaxPacketLength
= 64 * 1024;
114 bool ConvertDirectionToApi(const UsbEndpointDirection
& input
,
117 case usb_service::USB_DIRECTION_INBOUND
:
118 *output
= usb::DIRECTION_IN
;
120 case usb_service::USB_DIRECTION_OUTBOUND
:
121 *output
= usb::DIRECTION_OUT
;
129 bool ConvertSynchronizationTypeToApi(const UsbSynchronizationType
& input
,
130 usb::SynchronizationType
* output
) {
132 case usb_service::USB_SYNCHRONIZATION_NONE
:
133 *output
= usb::SYNCHRONIZATION_TYPE_NONE
;
135 case usb_service::USB_SYNCHRONIZATION_ASYNCHRONOUS
:
136 *output
= usb::SYNCHRONIZATION_TYPE_ASYNCHRONOUS
;
138 case usb_service::USB_SYNCHRONIZATION_ADAPTIVE
:
139 *output
= usb::SYNCHRONIZATION_TYPE_ADAPTIVE
;
141 case usb_service::USB_SYNCHRONIZATION_SYNCHRONOUS
:
142 *output
= usb::SYNCHRONIZATION_TYPE_SYNCHRONOUS
;
150 bool ConvertTransferTypeToApi(const UsbTransferType
& input
,
151 usb::TransferType
* output
) {
153 case usb_service::USB_TRANSFER_CONTROL
:
154 *output
= usb::TRANSFER_TYPE_CONTROL
;
156 case usb_service::USB_TRANSFER_INTERRUPT
:
157 *output
= usb::TRANSFER_TYPE_INTERRUPT
;
159 case usb_service::USB_TRANSFER_ISOCHRONOUS
:
160 *output
= usb::TRANSFER_TYPE_ISOCHRONOUS
;
162 case usb_service::USB_TRANSFER_BULK
:
163 *output
= usb::TRANSFER_TYPE_BULK
;
171 bool ConvertUsageTypeToApi(const UsbUsageType
& input
, usb::UsageType
* output
) {
173 case usb_service::USB_USAGE_DATA
:
174 *output
= usb::USAGE_TYPE_DATA
;
176 case usb_service::USB_USAGE_FEEDBACK
:
177 *output
= usb::USAGE_TYPE_FEEDBACK
;
179 case usb_service::USB_USAGE_EXPLICIT_FEEDBACK
:
180 *output
= usb::USAGE_TYPE_EXPLICITFEEDBACK
;
188 bool ConvertDirection(const Direction
& input
, UsbEndpointDirection
* output
) {
190 case usb::DIRECTION_IN
:
191 *output
= usb_service::USB_DIRECTION_INBOUND
;
193 case usb::DIRECTION_OUT
:
194 *output
= usb_service::USB_DIRECTION_OUTBOUND
;
202 bool ConvertRequestType(const RequestType
& input
,
203 UsbDeviceHandle::TransferRequestType
* output
) {
205 case usb::REQUEST_TYPE_STANDARD
:
206 *output
= UsbDeviceHandle::STANDARD
;
208 case usb::REQUEST_TYPE_CLASS
:
209 *output
= UsbDeviceHandle::CLASS
;
211 case usb::REQUEST_TYPE_VENDOR
:
212 *output
= UsbDeviceHandle::VENDOR
;
214 case usb::REQUEST_TYPE_RESERVED
:
215 *output
= UsbDeviceHandle::RESERVED
;
223 bool ConvertRecipient(const Recipient
& input
,
224 UsbDeviceHandle::TransferRecipient
* output
) {
226 case usb::RECIPIENT_DEVICE
:
227 *output
= UsbDeviceHandle::DEVICE
;
229 case usb::RECIPIENT_INTERFACE
:
230 *output
= UsbDeviceHandle::INTERFACE
;
232 case usb::RECIPIENT_ENDPOINT
:
233 *output
= UsbDeviceHandle::ENDPOINT
;
235 case usb::RECIPIENT_OTHER
:
236 *output
= UsbDeviceHandle::OTHER
;
245 bool GetTransferSize(const T
& input
, size_t* output
) {
246 if (input
.direction
== usb::DIRECTION_IN
) {
247 const int* length
= input
.length
.get();
248 if (length
&& *length
>= 0 &&
249 static_cast<size_t>(*length
) < kMaxTransferLength
) {
253 } else if (input
.direction
== usb::DIRECTION_OUT
) {
254 if (input
.data
.get()) {
255 *output
= input
.data
->size();
263 scoped_refptr
<net::IOBuffer
> CreateBufferForTransfer(
265 UsbEndpointDirection direction
,
267 if (size
>= kMaxTransferLength
)
270 // Allocate a |size|-bytes buffer, or a one-byte buffer if |size| is 0. This
271 // is due to an impedance mismatch between IOBuffer and URBs. An IOBuffer
272 // cannot represent a zero-length buffer, while an URB can.
273 scoped_refptr
<net::IOBuffer
> buffer
=
274 new net::IOBuffer(std::max(static_cast<size_t>(1), size
));
276 if (direction
== usb_service::USB_DIRECTION_INBOUND
) {
278 } else if (direction
== usb_service::USB_DIRECTION_OUTBOUND
) {
279 if (input
.data
.get() && size
<= input
.data
->size()) {
280 memcpy(buffer
->data(), input
.data
->data(), size
);
288 const char* ConvertTransferStatusToErrorString(const UsbTransferStatus status
) {
290 case usb_service::USB_TRANSFER_COMPLETED
:
292 case usb_service::USB_TRANSFER_ERROR
:
293 return kErrorGeneric
;
294 case usb_service::USB_TRANSFER_TIMEOUT
:
295 return kErrorTimeout
;
296 case usb_service::USB_TRANSFER_CANCELLED
:
297 return kErrorCancelled
;
298 case usb_service::USB_TRANSFER_STALLED
:
299 return kErrorStalled
;
300 case usb_service::USB_TRANSFER_DISCONNECT
:
301 return kErrorDisconnect
;
302 case usb_service::USB_TRANSFER_OVERFLOW
:
303 return kErrorOverflow
;
304 case usb_service::USB_TRANSFER_LENGTH_SHORT
:
305 return kErrorTransferLength
;
312 #if defined(OS_CHROMEOS)
313 void RequestUsbDevicesAccessHelper(
314 ScopedDeviceVector devices
,
315 std::vector
<scoped_refptr
<UsbDevice
> >::iterator i
,
317 const base::Callback
<void(ScopedDeviceVector result
)>& callback
,
322 i
= devices
->erase(i
);
324 if (i
== devices
->end()) {
325 callback
.Run(devices
.Pass());
328 (*i
)->RequestUsbAcess(interface_id
,
329 base::Bind(RequestUsbDevicesAccessHelper
,
330 base::Passed(devices
.Pass()),
336 void RequestUsbDevicesAccess(
337 ScopedDeviceVector devices
,
339 const base::Callback
<void(ScopedDeviceVector result
)>& callback
) {
340 if (devices
->empty()) {
341 callback
.Run(devices
.Pass());
344 std::vector
<scoped_refptr
<UsbDevice
> >::iterator i
= devices
->begin();
345 (*i
)->RequestUsbAcess(interface_id
,
346 base::Bind(RequestUsbDevicesAccessHelper
,
347 base::Passed(devices
.Pass()),
352 #endif // OS_CHROMEOS
354 base::DictionaryValue
* CreateTransferInfo(UsbTransferStatus status
,
355 scoped_refptr
<net::IOBuffer
> data
,
357 base::DictionaryValue
* result
= new base::DictionaryValue();
358 result
->SetInteger(kResultCodeKey
, status
);
359 result
->Set(kDataKey
,
360 base::BinaryValue::CreateWithCopiedBuffer(data
->data(), length
));
364 base::Value
* PopulateConnectionHandle(int handle
,
367 ConnectionHandle result
;
368 result
.handle
= handle
;
369 result
.vendor_id
= vendor_id
;
370 result
.product_id
= product_id
;
371 return result
.ToValue().release();
374 base::Value
* PopulateDevice(UsbDevice
* device
) {
376 result
.device
= device
->unique_id();
377 result
.vendor_id
= device
->vendor_id();
378 result
.product_id
= device
->product_id();
379 return result
.ToValue().release();
382 base::Value
* PopulateInterfaceDescriptor(
383 int interface_number
,
384 int alternate_setting
,
386 int interface_subclass
,
387 int interface_protocol
,
388 std::vector
<linked_ptr
<EndpointDescriptor
> >* endpoints
) {
389 InterfaceDescriptor descriptor
;
390 descriptor
.interface_number
= interface_number
;
391 descriptor
.alternate_setting
= alternate_setting
;
392 descriptor
.interface_class
= interface_class
;
393 descriptor
.interface_subclass
= interface_subclass
;
394 descriptor
.interface_protocol
= interface_protocol
;
395 descriptor
.endpoints
= *endpoints
;
396 return descriptor
.ToValue().release();
401 namespace extensions
{
403 UsbAsyncApiFunction::UsbAsyncApiFunction() : manager_(NULL
) {
406 UsbAsyncApiFunction::~UsbAsyncApiFunction() {
409 bool UsbAsyncApiFunction::PrePrepare() {
410 manager_
= ApiResourceManager
<UsbDeviceResource
>::Get(browser_context());
411 set_work_thread_id(BrowserThread::FILE);
412 return manager_
!= NULL
;
415 bool UsbAsyncApiFunction::Respond() {
416 return error_
.empty();
419 scoped_refptr
<UsbDevice
> UsbAsyncApiFunction::GetDeviceOrOrCompleteWithError(
420 const Device
& input_device
) {
421 const uint16_t vendor_id
= input_device
.vendor_id
;
422 const uint16_t product_id
= input_device
.product_id
;
423 UsbDevicePermission::CheckParam
param(
424 vendor_id
, product_id
, UsbDevicePermissionData::UNSPECIFIED_INTERFACE
);
425 if (!PermissionsData::CheckAPIPermissionWithParam(
426 GetExtension(), APIPermission::kUsbDevice
, ¶m
)) {
427 LOG(WARNING
) << "Insufficient permissions to access device.";
428 CompleteWithError(kErrorPermissionDenied
);
432 UsbService
* service
= UsbService::GetInstance();
434 CompleteWithError(kErrorInitService
);
437 scoped_refptr
<UsbDevice
> device
;
439 device
= service
->GetDeviceById(input_device
.device
);
442 CompleteWithError(kErrorNoDevice
);
446 if (device
->vendor_id() != input_device
.vendor_id
||
447 device
->product_id() != input_device
.product_id
) {
448 // Must act as if there is no such a device.
449 // Otherwise can be used to finger print unauthorized devices.
450 CompleteWithError(kErrorNoDevice
);
457 scoped_refptr
<UsbDeviceHandle
>
458 UsbAsyncApiFunction::GetDeviceHandleOrCompleteWithError(
459 const ConnectionHandle
& input_device_handle
) {
460 UsbDeviceResource
* resource
=
461 manager_
->Get(extension_
->id(), input_device_handle
.handle
);
463 CompleteWithError(kErrorNoDevice
);
467 if (!resource
->device() || !resource
->device()->GetDevice()) {
468 CompleteWithError(kErrorDisconnect
);
469 manager_
->Remove(extension_
->id(), input_device_handle
.handle
);
473 if (resource
->device()->GetDevice()->vendor_id() !=
474 input_device_handle
.vendor_id
||
475 resource
->device()->GetDevice()->product_id() !=
476 input_device_handle
.product_id
) {
477 CompleteWithError(kErrorNoDevice
);
481 return resource
->device();
484 void UsbAsyncApiFunction::RemoveUsbDeviceResource(int api_resource_id
) {
485 manager_
->Remove(extension_
->id(), api_resource_id
);
488 void UsbAsyncApiFunction::CompleteWithError(const std::string
& error
) {
490 AsyncWorkCompleted();
493 UsbAsyncApiTransferFunction::UsbAsyncApiTransferFunction() {
496 UsbAsyncApiTransferFunction::~UsbAsyncApiTransferFunction() {
499 void UsbAsyncApiTransferFunction::OnCompleted(UsbTransferStatus status
,
500 scoped_refptr
<net::IOBuffer
> data
,
502 if (status
!= usb_service::USB_TRANSFER_COMPLETED
)
503 SetError(ConvertTransferStatusToErrorString(status
));
505 SetResult(CreateTransferInfo(status
, data
, length
));
506 AsyncWorkCompleted();
509 bool UsbAsyncApiTransferFunction::ConvertDirectionSafely(
510 const Direction
& input
,
511 UsbEndpointDirection
* output
) {
512 const bool converted
= ConvertDirection(input
, output
);
514 SetError(kErrorConvertDirection
);
518 bool UsbAsyncApiTransferFunction::ConvertRequestTypeSafely(
519 const RequestType
& input
,
520 UsbDeviceHandle::TransferRequestType
* output
) {
521 const bool converted
= ConvertRequestType(input
, output
);
523 SetError(kErrorConvertRequestType
);
527 bool UsbAsyncApiTransferFunction::ConvertRecipientSafely(
528 const Recipient
& input
,
529 UsbDeviceHandle::TransferRecipient
* output
) {
530 const bool converted
= ConvertRecipient(input
, output
);
532 SetError(kErrorConvertRecipient
);
536 UsbFindDevicesFunction::UsbFindDevicesFunction() {
539 UsbFindDevicesFunction::~UsbFindDevicesFunction() {
542 bool UsbFindDevicesFunction::Prepare() {
543 parameters_
= FindDevices::Params::Create(*args_
);
544 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
548 void UsbFindDevicesFunction::AsyncWorkStart() {
549 scoped_ptr
<base::ListValue
> result(new base::ListValue());
550 const uint16_t vendor_id
= parameters_
->options
.vendor_id
;
551 const uint16_t product_id
= parameters_
->options
.product_id
;
552 int interface_id
= parameters_
->options
.interface_id
.get()
553 ? *parameters_
->options
.interface_id
.get()
554 : UsbDevicePermissionData::ANY_INTERFACE
;
555 UsbDevicePermission::CheckParam
param(vendor_id
, product_id
, interface_id
);
556 if (!PermissionsData::CheckAPIPermissionWithParam(
557 GetExtension(), APIPermission::kUsbDevice
, ¶m
)) {
558 LOG(WARNING
) << "Insufficient permissions to access device.";
559 CompleteWithError(kErrorPermissionDenied
);
563 UsbService
* service
= UsbService::GetInstance();
565 CompleteWithError(kErrorInitService
);
569 ScopedDeviceVector
devices(new DeviceVector());
570 service
->GetDevices(devices
.get());
572 for (DeviceVector::iterator it
= devices
->begin(); it
!= devices
->end();) {
573 if ((*it
)->vendor_id() != vendor_id
|| (*it
)->product_id() != product_id
) {
574 it
= devices
->erase(it
);
580 #if defined(OS_CHROMEOS)
581 RequestUsbDevicesAccess(
584 base::Bind(&UsbFindDevicesFunction::OpenDevices
, this));
586 OpenDevices(devices
.Pass());
587 #endif // OS_CHROMEOS
590 void UsbFindDevicesFunction::OpenDevices(ScopedDeviceVector devices
) {
591 base::ListValue
* result
= new base::ListValue();
593 for (size_t i
= 0; i
< devices
->size(); ++i
) {
594 scoped_refptr
<UsbDeviceHandle
> device_handle
= devices
->at(i
)->Open();
596 device_handles_
.push_back(device_handle
);
599 for (size_t i
= 0; i
< device_handles_
.size(); ++i
) {
600 UsbDeviceHandle
* const device_handle
= device_handles_
[i
].get();
601 UsbDeviceResource
* const resource
=
602 new UsbDeviceResource(extension_
->id(), device_handle
);
604 result
->Append(PopulateConnectionHandle(manager_
->Add(resource
),
605 parameters_
->options
.vendor_id
,
606 parameters_
->options
.product_id
));
610 AsyncWorkCompleted();
613 UsbGetDevicesFunction::UsbGetDevicesFunction() {
616 UsbGetDevicesFunction::~UsbGetDevicesFunction() {
619 bool UsbGetDevicesFunction::Prepare() {
620 parameters_
= GetDevices::Params::Create(*args_
);
621 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
625 void UsbGetDevicesFunction::AsyncWorkStart() {
626 scoped_ptr
<base::ListValue
> result(new base::ListValue());
628 const uint16_t vendor_id
= parameters_
->options
.vendor_id
;
629 const uint16_t product_id
= parameters_
->options
.product_id
;
630 UsbDevicePermission::CheckParam
param(
631 vendor_id
, product_id
, UsbDevicePermissionData::UNSPECIFIED_INTERFACE
);
632 if (!PermissionsData::CheckAPIPermissionWithParam(
633 GetExtension(), APIPermission::kUsbDevice
, ¶m
)) {
634 LOG(WARNING
) << "Insufficient permissions to access device.";
635 CompleteWithError(kErrorPermissionDenied
);
639 UsbService
* service
= UsbService::GetInstance();
641 CompleteWithError(kErrorInitService
);
645 DeviceVector devices
;
646 service
->GetDevices(&devices
);
648 for (DeviceVector::iterator it
= devices
.begin(); it
!= devices
.end();) {
649 if ((*it
)->vendor_id() != vendor_id
|| (*it
)->product_id() != product_id
) {
650 it
= devices
.erase(it
);
656 for (size_t i
= 0; i
< devices
.size(); ++i
) {
657 result
->Append(PopulateDevice(devices
[i
].get()));
660 SetResult(result
.release());
661 AsyncWorkCompleted();
664 UsbRequestAccessFunction::UsbRequestAccessFunction() {
667 UsbRequestAccessFunction::~UsbRequestAccessFunction() {
670 bool UsbRequestAccessFunction::Prepare() {
671 parameters_
= RequestAccess::Params::Create(*args_
);
672 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
676 void UsbRequestAccessFunction::AsyncWorkStart() {
677 #if defined(OS_CHROMEOS)
678 scoped_refptr
<UsbDevice
> device
=
679 GetDeviceOrOrCompleteWithError(parameters_
->device
);
683 device
->RequestUsbAcess(
684 parameters_
->interface_id
,
685 base::Bind(&UsbRequestAccessFunction::OnCompleted
, this));
687 SetResult(new base::FundamentalValue(false));
688 CompleteWithError(kErrorNotSupported
);
689 #endif // OS_CHROMEOS
692 void UsbRequestAccessFunction::OnCompleted(bool success
) {
693 SetResult(new base::FundamentalValue(success
));
694 AsyncWorkCompleted();
697 UsbOpenDeviceFunction::UsbOpenDeviceFunction() {
700 UsbOpenDeviceFunction::~UsbOpenDeviceFunction() {
703 bool UsbOpenDeviceFunction::Prepare() {
704 parameters_
= OpenDevice::Params::Create(*args_
);
705 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
709 void UsbOpenDeviceFunction::AsyncWorkStart() {
710 scoped_refptr
<UsbDevice
> device
=
711 GetDeviceOrOrCompleteWithError(parameters_
->device
);
715 handle_
= device
->Open();
717 SetError(kErrorOpen
);
718 AsyncWorkCompleted();
722 SetResult(PopulateConnectionHandle(
723 manager_
->Add(new UsbDeviceResource(extension_
->id(), handle_
)),
724 handle_
->GetDevice()->vendor_id(),
725 handle_
->GetDevice()->product_id()));
726 AsyncWorkCompleted();
729 UsbListInterfacesFunction::UsbListInterfacesFunction() {
732 UsbListInterfacesFunction::~UsbListInterfacesFunction() {
735 bool UsbListInterfacesFunction::Prepare() {
736 parameters_
= ListInterfaces::Params::Create(*args_
);
737 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
741 void UsbListInterfacesFunction::AsyncWorkStart() {
742 scoped_refptr
<UsbDeviceHandle
> device_handle
=
743 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
747 scoped_refptr
<UsbConfigDescriptor
> config
=
748 device_handle
->GetDevice()->ListInterfaces();
751 SetError(kErrorCannotListInterfaces
);
752 AsyncWorkCompleted();
756 result_
.reset(new base::ListValue());
758 for (size_t i
= 0, num_interfaces
= config
->GetNumInterfaces();
761 scoped_refptr
<const UsbInterfaceDescriptor
> usb_interface(
762 config
->GetInterface(i
));
763 for (size_t j
= 0, num_descriptors
= usb_interface
->GetNumAltSettings();
766 scoped_refptr
<const UsbInterfaceAltSettingDescriptor
> descriptor
=
767 usb_interface
->GetAltSetting(j
);
768 std::vector
<linked_ptr
<EndpointDescriptor
> > endpoints
;
769 for (size_t k
= 0, num_endpoints
= descriptor
->GetNumEndpoints();
772 scoped_refptr
<const UsbEndpointDescriptor
> endpoint
=
773 descriptor
->GetEndpoint(k
);
774 linked_ptr
<EndpointDescriptor
> endpoint_desc(new EndpointDescriptor());
778 SynchronizationType synchronization
;
781 if (!ConvertTransferTypeSafely(endpoint
->GetTransferType(), &type
) ||
782 !ConvertDirectionSafely(endpoint
->GetDirection(), &direction
) ||
783 !ConvertSynchronizationTypeSafely(
784 endpoint
->GetSynchronizationType(), &synchronization
) ||
785 !ConvertUsageTypeSafely(endpoint
->GetUsageType(), &usage
)) {
786 SetError(kErrorCannotListInterfaces
);
787 AsyncWorkCompleted();
791 endpoint_desc
->address
= endpoint
->GetAddress();
792 endpoint_desc
->type
= type
;
793 endpoint_desc
->direction
= direction
;
794 endpoint_desc
->maximum_packet_size
= endpoint
->GetMaximumPacketSize();
795 endpoint_desc
->synchronization
= synchronization
;
796 endpoint_desc
->usage
= usage
;
798 int* polling_interval
= new int;
799 endpoint_desc
->polling_interval
.reset(polling_interval
);
800 *polling_interval
= endpoint
->GetPollingInterval();
802 endpoints
.push_back(endpoint_desc
);
806 PopulateInterfaceDescriptor(descriptor
->GetInterfaceNumber(),
807 descriptor
->GetAlternateSetting(),
808 descriptor
->GetInterfaceClass(),
809 descriptor
->GetInterfaceSubclass(),
810 descriptor
->GetInterfaceProtocol(),
815 SetResult(result_
.release());
816 AsyncWorkCompleted();
819 bool UsbListInterfacesFunction::ConvertDirectionSafely(
820 const UsbEndpointDirection
& input
,
821 usb::Direction
* output
) {
822 const bool converted
= ConvertDirectionToApi(input
, output
);
824 SetError(kErrorConvertDirection
);
828 bool UsbListInterfacesFunction::ConvertSynchronizationTypeSafely(
829 const UsbSynchronizationType
& input
,
830 usb::SynchronizationType
* output
) {
831 const bool converted
= ConvertSynchronizationTypeToApi(input
, output
);
833 SetError(kErrorConvertSynchronizationType
);
837 bool UsbListInterfacesFunction::ConvertTransferTypeSafely(
838 const UsbTransferType
& input
,
839 usb::TransferType
* output
) {
840 const bool converted
= ConvertTransferTypeToApi(input
, output
);
842 SetError(kErrorConvertTransferType
);
846 bool UsbListInterfacesFunction::ConvertUsageTypeSafely(
847 const UsbUsageType
& input
,
848 usb::UsageType
* output
) {
849 const bool converted
= ConvertUsageTypeToApi(input
, output
);
851 SetError(kErrorConvertUsageType
);
855 UsbCloseDeviceFunction::UsbCloseDeviceFunction() {
858 UsbCloseDeviceFunction::~UsbCloseDeviceFunction() {
861 bool UsbCloseDeviceFunction::Prepare() {
862 parameters_
= CloseDevice::Params::Create(*args_
);
863 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
867 void UsbCloseDeviceFunction::AsyncWorkStart() {
868 scoped_refptr
<UsbDeviceHandle
> device_handle
=
869 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
873 device_handle
->Close();
874 RemoveUsbDeviceResource(parameters_
->handle
.handle
);
875 AsyncWorkCompleted();
878 UsbClaimInterfaceFunction::UsbClaimInterfaceFunction() {
881 UsbClaimInterfaceFunction::~UsbClaimInterfaceFunction() {
884 bool UsbClaimInterfaceFunction::Prepare() {
885 parameters_
= ClaimInterface::Params::Create(*args_
);
886 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
890 void UsbClaimInterfaceFunction::AsyncWorkStart() {
891 scoped_refptr
<UsbDeviceHandle
> device_handle
=
892 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
896 bool success
= device_handle
->ClaimInterface(parameters_
->interface_number
);
899 SetError(kErrorCannotClaimInterface
);
900 AsyncWorkCompleted();
903 UsbReleaseInterfaceFunction::UsbReleaseInterfaceFunction() {
906 UsbReleaseInterfaceFunction::~UsbReleaseInterfaceFunction() {
909 bool UsbReleaseInterfaceFunction::Prepare() {
910 parameters_
= ReleaseInterface::Params::Create(*args_
);
911 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
915 void UsbReleaseInterfaceFunction::AsyncWorkStart() {
916 scoped_refptr
<UsbDeviceHandle
> device_handle
=
917 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
921 bool success
= device_handle
->ReleaseInterface(parameters_
->interface_number
);
923 SetError(kErrorCannotReleaseInterface
);
924 AsyncWorkCompleted();
927 UsbSetInterfaceAlternateSettingFunction::
928 UsbSetInterfaceAlternateSettingFunction() {
931 UsbSetInterfaceAlternateSettingFunction::
932 ~UsbSetInterfaceAlternateSettingFunction() {
935 bool UsbSetInterfaceAlternateSettingFunction::Prepare() {
936 parameters_
= SetInterfaceAlternateSetting::Params::Create(*args_
);
937 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
941 void UsbSetInterfaceAlternateSettingFunction::AsyncWorkStart() {
942 scoped_refptr
<UsbDeviceHandle
> device_handle
=
943 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
947 bool success
= device_handle
->SetInterfaceAlternateSetting(
948 parameters_
->interface_number
, parameters_
->alternate_setting
);
950 SetError(kErrorCannotSetInterfaceAlternateSetting
);
952 AsyncWorkCompleted();
955 UsbControlTransferFunction::UsbControlTransferFunction() {
958 UsbControlTransferFunction::~UsbControlTransferFunction() {
961 bool UsbControlTransferFunction::Prepare() {
962 parameters_
= ControlTransfer::Params::Create(*args_
);
963 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
967 void UsbControlTransferFunction::AsyncWorkStart() {
968 scoped_refptr
<UsbDeviceHandle
> device_handle
=
969 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
973 const ControlTransferInfo
& transfer
= parameters_
->transfer_info
;
975 UsbEndpointDirection direction
;
976 UsbDeviceHandle::TransferRequestType request_type
;
977 UsbDeviceHandle::TransferRecipient recipient
;
980 if (!ConvertDirectionSafely(transfer
.direction
, &direction
) ||
981 !ConvertRequestTypeSafely(transfer
.request_type
, &request_type
) ||
982 !ConvertRecipientSafely(transfer
.recipient
, &recipient
)) {
983 AsyncWorkCompleted();
987 if (!GetTransferSize(transfer
, &size
)) {
988 CompleteWithError(kErrorInvalidTransferLength
);
992 scoped_refptr
<net::IOBuffer
> buffer
=
993 CreateBufferForTransfer(transfer
, direction
, size
);
995 CompleteWithError(kErrorMalformedParameters
);
999 device_handle
->ControlTransfer(
1009 base::Bind(&UsbControlTransferFunction::OnCompleted
, this));
1012 UsbBulkTransferFunction::UsbBulkTransferFunction() {
1015 UsbBulkTransferFunction::~UsbBulkTransferFunction() {
1018 bool UsbBulkTransferFunction::Prepare() {
1019 parameters_
= BulkTransfer::Params::Create(*args_
);
1020 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
1024 void UsbBulkTransferFunction::AsyncWorkStart() {
1025 scoped_refptr
<UsbDeviceHandle
> device_handle
=
1026 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
1030 const GenericTransferInfo
& transfer
= parameters_
->transfer_info
;
1032 UsbEndpointDirection direction
;
1035 if (!ConvertDirectionSafely(transfer
.direction
, &direction
)) {
1036 AsyncWorkCompleted();
1040 if (!GetTransferSize(transfer
, &size
)) {
1041 CompleteWithError(kErrorInvalidTransferLength
);
1045 scoped_refptr
<net::IOBuffer
> buffer
=
1046 CreateBufferForTransfer(transfer
, direction
, size
);
1047 if (!buffer
.get()) {
1048 CompleteWithError(kErrorMalformedParameters
);
1052 device_handle
->BulkTransfer(
1058 base::Bind(&UsbBulkTransferFunction::OnCompleted
, this));
1061 UsbInterruptTransferFunction::UsbInterruptTransferFunction() {
1064 UsbInterruptTransferFunction::~UsbInterruptTransferFunction() {
1067 bool UsbInterruptTransferFunction::Prepare() {
1068 parameters_
= InterruptTransfer::Params::Create(*args_
);
1069 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
1073 void UsbInterruptTransferFunction::AsyncWorkStart() {
1074 scoped_refptr
<UsbDeviceHandle
> device_handle
=
1075 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
1079 const GenericTransferInfo
& transfer
= parameters_
->transfer_info
;
1081 UsbEndpointDirection direction
;
1084 if (!ConvertDirectionSafely(transfer
.direction
, &direction
)) {
1085 AsyncWorkCompleted();
1089 if (!GetTransferSize(transfer
, &size
)) {
1090 CompleteWithError(kErrorInvalidTransferLength
);
1094 scoped_refptr
<net::IOBuffer
> buffer
=
1095 CreateBufferForTransfer(transfer
, direction
, size
);
1096 if (!buffer
.get()) {
1097 CompleteWithError(kErrorMalformedParameters
);
1101 device_handle
->InterruptTransfer(
1107 base::Bind(&UsbInterruptTransferFunction::OnCompleted
, this));
1110 UsbIsochronousTransferFunction::UsbIsochronousTransferFunction() {
1113 UsbIsochronousTransferFunction::~UsbIsochronousTransferFunction() {
1116 bool UsbIsochronousTransferFunction::Prepare() {
1117 parameters_
= IsochronousTransfer::Params::Create(*args_
);
1118 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
1122 void UsbIsochronousTransferFunction::AsyncWorkStart() {
1123 scoped_refptr
<UsbDeviceHandle
> device_handle
=
1124 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
1128 const IsochronousTransferInfo
& transfer
= parameters_
->transfer_info
;
1129 const GenericTransferInfo
& generic_transfer
= transfer
.transfer_info
;
1132 UsbEndpointDirection direction
;
1134 if (!ConvertDirectionSafely(generic_transfer
.direction
, &direction
)) {
1135 AsyncWorkCompleted();
1138 if (!GetTransferSize(generic_transfer
, &size
)) {
1139 CompleteWithError(kErrorInvalidTransferLength
);
1142 if (transfer
.packets
< 0 || transfer
.packets
>= kMaxPackets
) {
1143 CompleteWithError(kErrorInvalidNumberOfPackets
);
1146 unsigned int packets
= transfer
.packets
;
1147 if (transfer
.packet_length
< 0 ||
1148 transfer
.packet_length
>= kMaxPacketLength
) {
1149 CompleteWithError(kErrorInvalidPacketLength
);
1152 unsigned int packet_length
= transfer
.packet_length
;
1153 const uint64 total_length
= packets
* packet_length
;
1154 if (packets
> size
|| total_length
> size
) {
1155 CompleteWithError(kErrorTransferLength
);
1159 scoped_refptr
<net::IOBuffer
> buffer
=
1160 CreateBufferForTransfer(generic_transfer
, direction
, size
);
1161 if (!buffer
.get()) {
1162 CompleteWithError(kErrorMalformedParameters
);
1166 device_handle
->IsochronousTransfer(
1168 generic_transfer
.endpoint
,
1174 base::Bind(&UsbIsochronousTransferFunction::OnCompleted
, this));
1177 UsbResetDeviceFunction::UsbResetDeviceFunction() {
1180 UsbResetDeviceFunction::~UsbResetDeviceFunction() {
1183 bool UsbResetDeviceFunction::Prepare() {
1184 parameters_
= ResetDevice::Params::Create(*args_
);
1185 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
1189 void UsbResetDeviceFunction::AsyncWorkStart() {
1190 scoped_refptr
<UsbDeviceHandle
> device_handle
=
1191 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
1195 bool success
= device_handle
->ResetDevice();
1197 device_handle
->Close();
1198 RemoveUsbDeviceResource(parameters_
->handle
.handle
);
1199 SetResult(new base::FundamentalValue(false));
1200 CompleteWithError(kErrorResetDevice
);
1204 SetResult(new base::FundamentalValue(true));
1205 AsyncWorkCompleted();
1208 } // namespace extensions