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 "device/core/device_client.h"
13 #include "device/usb/usb_device_handle.h"
14 #include "device/usb/usb_service.h"
15 #include "extensions/browser/api/usb/usb_device_resource.h"
16 #include "extensions/browser/extension_system.h"
17 #include "extensions/common/api/usb.h"
18 #include "extensions/common/permissions/permissions_data.h"
19 #include "extensions/common/permissions/usb_device_permission.h"
21 namespace usb
= extensions::core_api::usb
;
22 namespace BulkTransfer
= usb::BulkTransfer
;
23 namespace ClaimInterface
= usb::ClaimInterface
;
24 namespace CloseDevice
= usb::CloseDevice
;
25 namespace ControlTransfer
= usb::ControlTransfer
;
26 namespace FindDevices
= usb::FindDevices
;
27 namespace GetDevices
= usb::GetDevices
;
28 namespace InterruptTransfer
= usb::InterruptTransfer
;
29 namespace IsochronousTransfer
= usb::IsochronousTransfer
;
30 namespace GetConfiguration
= usb::GetConfiguration
;
31 namespace ListInterfaces
= usb::ListInterfaces
;
32 namespace OpenDevice
= usb::OpenDevice
;
33 namespace ReleaseInterface
= usb::ReleaseInterface
;
34 namespace RequestAccess
= usb::RequestAccess
;
35 namespace ResetDevice
= usb::ResetDevice
;
36 namespace SetInterfaceAlternateSetting
= usb::SetInterfaceAlternateSetting
;
38 using content::BrowserThread
;
39 using usb::ConfigDescriptor
;
40 using usb::ControlTransferInfo
;
41 using usb::ConnectionHandle
;
44 using usb::EndpointDescriptor
;
45 using usb::GenericTransferInfo
;
46 using usb::InterfaceDescriptor
;
47 using usb::IsochronousTransferInfo
;
49 using usb::RequestType
;
50 using usb::SynchronizationType
;
51 using usb::TransferType
;
53 using device::UsbConfigDescriptor
;
54 using device::UsbDevice
;
55 using device::UsbDeviceFilter
;
56 using device::UsbDeviceHandle
;
57 using device::UsbEndpointDescriptor
;
58 using device::UsbEndpointDirection
;
59 using device::UsbInterfaceDescriptor
;
60 using device::UsbService
;
61 using device::UsbSynchronizationType
;
62 using device::UsbTransferStatus
;
63 using device::UsbTransferType
;
64 using device::UsbUsageType
;
66 typedef std::vector
<scoped_refptr
<UsbDevice
> > DeviceVector
;
67 typedef scoped_ptr
<DeviceVector
> ScopedDeviceVector
;
71 const char kDataKey
[] = "data";
72 const char kResultCodeKey
[] = "resultCode";
74 const char kErrorInitService
[] = "Failed to initialize USB service.";
76 const char kErrorOpen
[] = "Failed to open device.";
77 const char kErrorCancelled
[] = "Transfer was cancelled.";
78 const char kErrorDisconnect
[] = "Device disconnected.";
79 const char kErrorGeneric
[] = "Transfer failed.";
80 #if !defined(OS_CHROMEOS)
81 const char kErrorNotSupported
[] = "Not supported on this platform.";
83 const char kErrorOverflow
[] = "Inbound transfer overflow.";
84 const char kErrorStalled
[] = "Transfer stalled.";
85 const char kErrorTimeout
[] = "Transfer timed out.";
86 const char kErrorTransferLength
[] = "Transfer length is insufficient.";
87 const char kErrorCannotClaimInterface
[] = "Error claiming interface.";
88 const char kErrorCannotReleaseInterface
[] = "Error releasing interface.";
89 const char kErrorCannotSetInterfaceAlternateSetting
[] =
90 "Error setting alternate interface setting.";
91 const char kErrorConvertDirection
[] = "Invalid transfer direction.";
92 const char kErrorConvertRecipient
[] = "Invalid transfer recipient.";
93 const char kErrorConvertRequestType
[] = "Invalid request type.";
94 const char kErrorMalformedParameters
[] = "Error parsing parameters.";
95 const char kErrorNoDevice
[] = "No such device.";
96 const char kErrorPermissionDenied
[] = "Permission to access device was denied";
97 const char kErrorInvalidTransferLength
[] =
98 "Transfer length must be a positive number less than 104,857,600.";
99 const char kErrorInvalidNumberOfPackets
[] =
100 "Number of packets must be a positive number less than 4,194,304.";
101 const char kErrorInvalidPacketLength
[] =
102 "Packet length must be a positive number less than 65,536.";
103 const char kErrorResetDevice
[] =
104 "Error resetting the device. The device has been closed.";
106 const size_t kMaxTransferLength
= 100 * 1024 * 1024;
107 const int kMaxPackets
= 4 * 1024 * 1024;
108 const int kMaxPacketLength
= 64 * 1024;
110 bool ConvertDirectionFromApi(const Direction
& input
,
111 UsbEndpointDirection
* output
) {
113 case usb::DIRECTION_IN
:
114 *output
= device::USB_DIRECTION_INBOUND
;
116 case usb::DIRECTION_OUT
:
117 *output
= device::USB_DIRECTION_OUTBOUND
;
125 bool ConvertRequestTypeFromApi(const RequestType
& input
,
126 UsbDeviceHandle::TransferRequestType
* output
) {
128 case usb::REQUEST_TYPE_STANDARD
:
129 *output
= UsbDeviceHandle::STANDARD
;
131 case usb::REQUEST_TYPE_CLASS
:
132 *output
= UsbDeviceHandle::CLASS
;
134 case usb::REQUEST_TYPE_VENDOR
:
135 *output
= UsbDeviceHandle::VENDOR
;
137 case usb::REQUEST_TYPE_RESERVED
:
138 *output
= UsbDeviceHandle::RESERVED
;
146 bool ConvertRecipientFromApi(const Recipient
& input
,
147 UsbDeviceHandle::TransferRecipient
* output
) {
149 case usb::RECIPIENT_DEVICE
:
150 *output
= UsbDeviceHandle::DEVICE
;
152 case usb::RECIPIENT_INTERFACE
:
153 *output
= UsbDeviceHandle::INTERFACE
;
155 case usb::RECIPIENT_ENDPOINT
:
156 *output
= UsbDeviceHandle::ENDPOINT
;
158 case usb::RECIPIENT_OTHER
:
159 *output
= UsbDeviceHandle::OTHER
;
168 bool GetTransferSize(const T
& input
, size_t* output
) {
169 if (input
.direction
== usb::DIRECTION_IN
) {
170 const int* length
= input
.length
.get();
171 if (length
&& *length
>= 0 &&
172 static_cast<size_t>(*length
) < kMaxTransferLength
) {
176 } else if (input
.direction
== usb::DIRECTION_OUT
) {
177 if (input
.data
.get()) {
178 *output
= input
.data
->size();
186 scoped_refptr
<net::IOBuffer
> CreateBufferForTransfer(
188 UsbEndpointDirection direction
,
190 if (size
>= kMaxTransferLength
)
193 // Allocate a |size|-bytes buffer, or a one-byte buffer if |size| is 0. This
194 // is due to an impedance mismatch between IOBuffer and URBs. An IOBuffer
195 // cannot represent a zero-length buffer, while an URB can.
196 scoped_refptr
<net::IOBuffer
> buffer
=
197 new net::IOBuffer(std::max(static_cast<size_t>(1), size
));
199 if (direction
== device::USB_DIRECTION_INBOUND
) {
201 } else if (direction
== device::USB_DIRECTION_OUTBOUND
) {
202 if (input
.data
.get() && size
<= input
.data
->size()) {
203 memcpy(buffer
->data(), input
.data
->data(), size
);
211 const char* ConvertTransferStatusToApi(const UsbTransferStatus status
) {
213 case device::USB_TRANSFER_COMPLETED
:
215 case device::USB_TRANSFER_ERROR
:
216 return kErrorGeneric
;
217 case device::USB_TRANSFER_TIMEOUT
:
218 return kErrorTimeout
;
219 case device::USB_TRANSFER_CANCELLED
:
220 return kErrorCancelled
;
221 case device::USB_TRANSFER_STALLED
:
222 return kErrorStalled
;
223 case device::USB_TRANSFER_DISCONNECT
:
224 return kErrorDisconnect
;
225 case device::USB_TRANSFER_OVERFLOW
:
226 return kErrorOverflow
;
227 case device::USB_TRANSFER_LENGTH_SHORT
:
228 return kErrorTransferLength
;
235 #if defined(OS_CHROMEOS)
236 void RequestUsbDevicesAccessHelper(
237 ScopedDeviceVector devices
,
238 std::vector
<scoped_refptr
<UsbDevice
> >::iterator i
,
240 const base::Callback
<void(ScopedDeviceVector result
)>& callback
,
245 i
= devices
->erase(i
);
247 if (i
== devices
->end()) {
248 callback
.Run(devices
.Pass());
251 (*i
)->RequestUsbAccess(interface_id
,
252 base::Bind(RequestUsbDevicesAccessHelper
,
253 base::Passed(devices
.Pass()),
259 void RequestUsbDevicesAccess(
260 ScopedDeviceVector devices
,
262 const base::Callback
<void(ScopedDeviceVector result
)>& callback
) {
263 if (devices
->empty()) {
264 callback
.Run(devices
.Pass());
267 std::vector
<scoped_refptr
<UsbDevice
> >::iterator i
= devices
->begin();
268 (*i
)->RequestUsbAccess(interface_id
,
269 base::Bind(RequestUsbDevicesAccessHelper
,
270 base::Passed(devices
.Pass()),
275 #endif // OS_CHROMEOS
277 base::DictionaryValue
* CreateTransferInfo(UsbTransferStatus status
,
278 scoped_refptr
<net::IOBuffer
> data
,
280 base::DictionaryValue
* result
= new base::DictionaryValue();
281 result
->SetInteger(kResultCodeKey
, status
);
282 result
->Set(kDataKey
,
283 base::BinaryValue::CreateWithCopiedBuffer(data
->data(), length
));
287 base::Value
* PopulateConnectionHandle(int handle
,
290 ConnectionHandle result
;
291 result
.handle
= handle
;
292 result
.vendor_id
= vendor_id
;
293 result
.product_id
= product_id
;
294 return result
.ToValue().release();
297 base::Value
* PopulateDevice(UsbDevice
* device
) {
299 result
.device
= device
->unique_id();
300 result
.vendor_id
= device
->vendor_id();
301 result
.product_id
= device
->product_id();
302 return result
.ToValue().release();
305 TransferType
ConvertTransferTypeToApi(const UsbTransferType
& input
) {
307 case device::USB_TRANSFER_CONTROL
:
308 return usb::TRANSFER_TYPE_CONTROL
;
309 case device::USB_TRANSFER_INTERRUPT
:
310 return usb::TRANSFER_TYPE_INTERRUPT
;
311 case device::USB_TRANSFER_ISOCHRONOUS
:
312 return usb::TRANSFER_TYPE_ISOCHRONOUS
;
313 case device::USB_TRANSFER_BULK
:
314 return usb::TRANSFER_TYPE_BULK
;
317 return usb::TRANSFER_TYPE_NONE
;
321 Direction
ConvertDirectionToApi(const UsbEndpointDirection
& input
) {
323 case device::USB_DIRECTION_INBOUND
:
324 return usb::DIRECTION_IN
;
325 case device::USB_DIRECTION_OUTBOUND
:
326 return usb::DIRECTION_OUT
;
329 return usb::DIRECTION_NONE
;
333 SynchronizationType
ConvertSynchronizationTypeToApi(
334 const UsbSynchronizationType
& input
) {
336 case device::USB_SYNCHRONIZATION_NONE
:
337 return usb::SYNCHRONIZATION_TYPE_NONE
;
338 case device::USB_SYNCHRONIZATION_ASYNCHRONOUS
:
339 return usb::SYNCHRONIZATION_TYPE_ASYNCHRONOUS
;
340 case device::USB_SYNCHRONIZATION_ADAPTIVE
:
341 return usb::SYNCHRONIZATION_TYPE_ADAPTIVE
;
342 case device::USB_SYNCHRONIZATION_SYNCHRONOUS
:
343 return usb::SYNCHRONIZATION_TYPE_SYNCHRONOUS
;
346 return usb::SYNCHRONIZATION_TYPE_NONE
;
350 UsageType
ConvertUsageTypeToApi(const UsbUsageType
& input
) {
352 case device::USB_USAGE_DATA
:
353 return usb::USAGE_TYPE_DATA
;
354 case device::USB_USAGE_FEEDBACK
:
355 return usb::USAGE_TYPE_FEEDBACK
;
356 case device::USB_USAGE_EXPLICIT_FEEDBACK
:
357 return usb::USAGE_TYPE_EXPLICITFEEDBACK
;
360 return usb::USAGE_TYPE_NONE
;
364 void ConvertEndpointDescriptor(const UsbEndpointDescriptor
& input
,
365 EndpointDescriptor
* output
) {
366 output
->address
= input
.address
;
367 output
->type
= ConvertTransferTypeToApi(input
.transfer_type
);
368 output
->direction
= ConvertDirectionToApi(input
.direction
);
369 output
->maximum_packet_size
= input
.maximum_packet_size
;
370 output
->synchronization
=
371 ConvertSynchronizationTypeToApi(input
.synchronization_type
);
372 output
->usage
= ConvertUsageTypeToApi(input
.usage_type
);
373 output
->polling_interval
.reset(new int(input
.polling_interval
));
374 if (input
.extra_data
.size() > 0) {
376 std::string(reinterpret_cast<const char*>(&input
.extra_data
[0]),
377 input
.extra_data
.size());
381 void ConvertInterfaceDescriptor(const UsbInterfaceDescriptor
& input
,
382 InterfaceDescriptor
* output
) {
383 output
->interface_number
= input
.interface_number
;
384 output
->alternate_setting
= input
.alternate_setting
;
385 output
->interface_class
= input
.interface_class
;
386 output
->interface_subclass
= input
.interface_subclass
;
387 output
->interface_protocol
= input
.interface_protocol
;
388 for (UsbEndpointDescriptor::Iterator endpointIt
= input
.endpoints
.begin();
389 endpointIt
!= input
.endpoints
.end();
391 linked_ptr
<EndpointDescriptor
> endpoint(new EndpointDescriptor
);
392 ConvertEndpointDescriptor(*endpointIt
, endpoint
.get());
393 output
->endpoints
.push_back(endpoint
);
395 if (input
.extra_data
.size() > 0) {
397 std::string(reinterpret_cast<const char*>(&input
.extra_data
[0]),
398 input
.extra_data
.size());
402 void ConvertConfigDescriptor(const UsbConfigDescriptor
& input
,
403 ConfigDescriptor
* output
) {
404 output
->configuration_value
= input
.configuration_value
;
405 output
->self_powered
= input
.self_powered
;
406 output
->remote_wakeup
= input
.remote_wakeup
;
407 output
->max_power
= input
.maximum_power
;
408 for (UsbInterfaceDescriptor::Iterator interfaceIt
= input
.interfaces
.begin();
409 interfaceIt
!= input
.interfaces
.end();
411 linked_ptr
<InterfaceDescriptor
> interface(new InterfaceDescriptor
);
412 ConvertInterfaceDescriptor(*interfaceIt
, interface
.get());
413 output
->interfaces
.push_back(interface
);
415 if (input
.extra_data
.size() > 0) {
417 std::string(reinterpret_cast<const char*>(&input
.extra_data
[0]),
418 input
.extra_data
.size());
424 namespace extensions
{
426 UsbAsyncApiFunction::UsbAsyncApiFunction() : manager_(NULL
) {
429 UsbAsyncApiFunction::~UsbAsyncApiFunction() {
432 bool UsbAsyncApiFunction::PrePrepare() {
433 manager_
= ApiResourceManager
<UsbDeviceResource
>::Get(browser_context());
434 set_work_thread_id(BrowserThread::FILE);
435 return manager_
!= NULL
;
438 bool UsbAsyncApiFunction::Respond() {
439 return error_
.empty();
443 void UsbAsyncApiFunction::CreateDeviceFilter(const usb::DeviceFilter
& input
,
444 UsbDeviceFilter
* output
) {
445 if (input
.vendor_id
) {
446 output
->SetVendorId(*input
.vendor_id
);
448 if (input
.product_id
) {
449 output
->SetProductId(*input
.product_id
);
451 if (input
.interface_class
) {
452 output
->SetInterfaceClass(*input
.interface_class
);
454 if (input
.interface_subclass
) {
455 output
->SetInterfaceSubclass(*input
.interface_subclass
);
457 if (input
.interface_protocol
) {
458 output
->SetInterfaceProtocol(*input
.interface_protocol
);
462 bool UsbAsyncApiFunction::HasDevicePermission(scoped_refptr
<UsbDevice
> device
) {
463 UsbDevicePermission::CheckParam
param(
465 device
->product_id(),
466 UsbDevicePermissionData::UNSPECIFIED_INTERFACE
);
467 return extension()->permissions_data()->CheckAPIPermissionWithParam(
468 APIPermission::kUsbDevice
, ¶m
);
471 scoped_refptr
<UsbDevice
> UsbAsyncApiFunction::GetDeviceOrCompleteWithError(
472 const Device
& input_device
) {
473 UsbService
* service
= device::DeviceClient::Get()->GetUsbService();
475 CompleteWithError(kErrorInitService
);
479 scoped_refptr
<UsbDevice
> device
= service
->GetDeviceById(input_device
.device
);
481 CompleteWithError(kErrorNoDevice
);
485 if (!HasDevicePermission(device
)) {
486 // Must act as if there is no such a device.
487 // Otherwise can be used to finger print unauthorized devices.
488 CompleteWithError(kErrorNoDevice
);
495 scoped_refptr
<UsbDeviceHandle
>
496 UsbAsyncApiFunction::GetDeviceHandleOrCompleteWithError(
497 const ConnectionHandle
& input_device_handle
) {
498 UsbDeviceResource
* resource
=
499 manager_
->Get(extension_
->id(), input_device_handle
.handle
);
501 CompleteWithError(kErrorNoDevice
);
505 if (!resource
->device().get() || !resource
->device()->GetDevice().get()) {
506 CompleteWithError(kErrorDisconnect
);
507 manager_
->Remove(extension_
->id(), input_device_handle
.handle
);
511 if (resource
->device()->GetDevice()->vendor_id() !=
512 input_device_handle
.vendor_id
||
513 resource
->device()->GetDevice()->product_id() !=
514 input_device_handle
.product_id
) {
515 CompleteWithError(kErrorNoDevice
);
519 return resource
->device();
522 void UsbAsyncApiFunction::RemoveUsbDeviceResource(int api_resource_id
) {
523 manager_
->Remove(extension_
->id(), api_resource_id
);
526 void UsbAsyncApiFunction::CompleteWithError(const std::string
& error
) {
528 AsyncWorkCompleted();
531 UsbAsyncApiTransferFunction::UsbAsyncApiTransferFunction() {
534 UsbAsyncApiTransferFunction::~UsbAsyncApiTransferFunction() {
537 void UsbAsyncApiTransferFunction::OnCompleted(UsbTransferStatus status
,
538 scoped_refptr
<net::IOBuffer
> data
,
540 if (status
!= device::USB_TRANSFER_COMPLETED
)
541 SetError(ConvertTransferStatusToApi(status
));
543 SetResult(CreateTransferInfo(status
, data
, length
));
544 AsyncWorkCompleted();
547 bool UsbAsyncApiTransferFunction::ConvertDirectionSafely(
548 const Direction
& input
,
549 UsbEndpointDirection
* output
) {
550 const bool converted
= ConvertDirectionFromApi(input
, output
);
552 SetError(kErrorConvertDirection
);
556 bool UsbAsyncApiTransferFunction::ConvertRequestTypeSafely(
557 const RequestType
& input
,
558 UsbDeviceHandle::TransferRequestType
* output
) {
559 const bool converted
= ConvertRequestTypeFromApi(input
, output
);
561 SetError(kErrorConvertRequestType
);
565 bool UsbAsyncApiTransferFunction::ConvertRecipientSafely(
566 const Recipient
& input
,
567 UsbDeviceHandle::TransferRecipient
* output
) {
568 const bool converted
= ConvertRecipientFromApi(input
, output
);
570 SetError(kErrorConvertRecipient
);
574 UsbFindDevicesFunction::UsbFindDevicesFunction() {
577 UsbFindDevicesFunction::~UsbFindDevicesFunction() {
580 bool UsbFindDevicesFunction::Prepare() {
581 parameters_
= FindDevices::Params::Create(*args_
);
582 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
586 void UsbFindDevicesFunction::AsyncWorkStart() {
587 scoped_ptr
<base::ListValue
> result(new base::ListValue());
588 const uint16_t vendor_id
= parameters_
->options
.vendor_id
;
589 const uint16_t product_id
= parameters_
->options
.product_id
;
590 int interface_id
= parameters_
->options
.interface_id
.get()
591 ? *parameters_
->options
.interface_id
.get()
592 : UsbDevicePermissionData::ANY_INTERFACE
;
593 UsbDevicePermission::CheckParam
param(vendor_id
, product_id
, interface_id
);
594 if (!extension()->permissions_data()->CheckAPIPermissionWithParam(
595 APIPermission::kUsbDevice
, ¶m
)) {
596 LOG(WARNING
) << "Insufficient permissions to access device.";
597 CompleteWithError(kErrorPermissionDenied
);
601 UsbService
* service
= device::DeviceClient::Get()->GetUsbService();
603 CompleteWithError(kErrorInitService
);
607 ScopedDeviceVector
devices(new DeviceVector());
608 service
->GetDevices(devices
.get());
610 for (DeviceVector::iterator it
= devices
->begin(); it
!= devices
->end();) {
611 if ((*it
)->vendor_id() != vendor_id
|| (*it
)->product_id() != product_id
) {
612 it
= devices
->erase(it
);
618 #if defined(OS_CHROMEOS)
619 RequestUsbDevicesAccess(
622 base::Bind(&UsbFindDevicesFunction::OpenDevices
, this));
624 OpenDevices(devices
.Pass());
625 #endif // OS_CHROMEOS
628 void UsbFindDevicesFunction::OpenDevices(ScopedDeviceVector devices
) {
629 base::ListValue
* result
= new base::ListValue();
631 for (size_t i
= 0; i
< devices
->size(); ++i
) {
632 scoped_refptr
<UsbDeviceHandle
> device_handle
= devices
->at(i
)->Open();
633 if (device_handle
.get())
634 device_handles_
.push_back(device_handle
);
637 for (size_t i
= 0; i
< device_handles_
.size(); ++i
) {
638 UsbDeviceHandle
* const device_handle
= device_handles_
[i
].get();
639 UsbDeviceResource
* const resource
=
640 new UsbDeviceResource(extension_
->id(), device_handle
);
642 result
->Append(PopulateConnectionHandle(manager_
->Add(resource
),
643 parameters_
->options
.vendor_id
,
644 parameters_
->options
.product_id
));
648 AsyncWorkCompleted();
651 UsbGetDevicesFunction::UsbGetDevicesFunction() {
654 UsbGetDevicesFunction::~UsbGetDevicesFunction() {
657 bool UsbGetDevicesFunction::Prepare() {
658 parameters_
= GetDevices::Params::Create(*args_
);
659 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
663 void UsbGetDevicesFunction::AsyncWorkStart() {
664 std::vector
<UsbDeviceFilter
> filters
;
665 if (parameters_
->options
.filters
) {
666 filters
.resize(parameters_
->options
.filters
->size());
667 for (size_t i
= 0; i
< parameters_
->options
.filters
->size(); ++i
) {
668 CreateDeviceFilter(*parameters_
->options
.filters
->at(i
).get(),
672 if (parameters_
->options
.vendor_id
) {
673 filters
.resize(filters
.size() + 1);
674 filters
.back().SetVendorId(*parameters_
->options
.vendor_id
);
675 if (parameters_
->options
.product_id
) {
676 filters
.back().SetProductId(*parameters_
->options
.product_id
);
680 UsbService
* service
= device::DeviceClient::Get()->GetUsbService();
682 CompleteWithError(kErrorInitService
);
686 DeviceVector devices
;
687 service
->GetDevices(&devices
);
689 scoped_ptr
<base::ListValue
> result(new base::ListValue());
690 for (DeviceVector::iterator it
= devices
.begin(); it
!= devices
.end(); ++it
) {
691 scoped_refptr
<UsbDevice
> device
= *it
;
692 if ((filters
.empty() || UsbDeviceFilter::MatchesAny(device
, filters
)) &&
693 HasDevicePermission(device
)) {
694 result
->Append(PopulateDevice(it
->get()));
698 SetResult(result
.release());
699 AsyncWorkCompleted();
702 UsbRequestAccessFunction::UsbRequestAccessFunction() {
705 UsbRequestAccessFunction::~UsbRequestAccessFunction() {
708 bool UsbRequestAccessFunction::Prepare() {
709 parameters_
= RequestAccess::Params::Create(*args_
);
710 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
714 void UsbRequestAccessFunction::AsyncWorkStart() {
715 #if defined(OS_CHROMEOS)
716 scoped_refptr
<UsbDevice
> device
=
717 GetDeviceOrCompleteWithError(parameters_
->device
);
721 device
->RequestUsbAccess(
722 parameters_
->interface_id
,
723 base::Bind(&UsbRequestAccessFunction::OnCompleted
, this));
725 SetResult(new base::FundamentalValue(false));
726 CompleteWithError(kErrorNotSupported
);
727 #endif // OS_CHROMEOS
730 void UsbRequestAccessFunction::OnCompleted(bool success
) {
731 SetResult(new base::FundamentalValue(success
));
732 AsyncWorkCompleted();
735 UsbOpenDeviceFunction::UsbOpenDeviceFunction() {
738 UsbOpenDeviceFunction::~UsbOpenDeviceFunction() {
741 bool UsbOpenDeviceFunction::Prepare() {
742 parameters_
= OpenDevice::Params::Create(*args_
);
743 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
747 void UsbOpenDeviceFunction::AsyncWorkStart() {
748 scoped_refptr
<UsbDevice
> device
=
749 GetDeviceOrCompleteWithError(parameters_
->device
);
753 handle_
= device
->Open();
754 if (!handle_
.get()) {
755 SetError(kErrorOpen
);
756 AsyncWorkCompleted();
760 SetResult(PopulateConnectionHandle(
761 manager_
->Add(new UsbDeviceResource(extension_
->id(), handle_
)),
762 handle_
->GetDevice()->vendor_id(),
763 handle_
->GetDevice()->product_id()));
764 AsyncWorkCompleted();
767 UsbGetConfigurationFunction::UsbGetConfigurationFunction() {
770 UsbGetConfigurationFunction::~UsbGetConfigurationFunction() {
773 bool UsbGetConfigurationFunction::Prepare() {
774 parameters_
= GetConfiguration::Params::Create(*args_
);
775 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
779 void UsbGetConfigurationFunction::AsyncWorkStart() {
780 scoped_refptr
<UsbDeviceHandle
> device_handle
=
781 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
782 if (!device_handle
.get()) {
786 ConfigDescriptor config
;
787 ConvertConfigDescriptor(device_handle
->GetDevice()->GetConfiguration(),
790 SetResult(config
.ToValue().release());
791 AsyncWorkCompleted();
794 UsbListInterfacesFunction::UsbListInterfacesFunction() {
797 UsbListInterfacesFunction::~UsbListInterfacesFunction() {
800 bool UsbListInterfacesFunction::Prepare() {
801 parameters_
= ListInterfaces::Params::Create(*args_
);
802 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
806 void UsbListInterfacesFunction::AsyncWorkStart() {
807 scoped_refptr
<UsbDeviceHandle
> device_handle
=
808 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
809 if (!device_handle
.get()) {
813 ConfigDescriptor config
;
814 ConvertConfigDescriptor(device_handle
->GetDevice()->GetConfiguration(),
817 scoped_ptr
<base::ListValue
> result(new base::ListValue
);
818 for (size_t i
= 0; i
< config
.interfaces
.size(); ++i
) {
819 result
->Append(config
.interfaces
[i
]->ToValue().release());
822 SetResult(result
.release());
823 AsyncWorkCompleted();
826 UsbCloseDeviceFunction::UsbCloseDeviceFunction() {
829 UsbCloseDeviceFunction::~UsbCloseDeviceFunction() {
832 bool UsbCloseDeviceFunction::Prepare() {
833 parameters_
= CloseDevice::Params::Create(*args_
);
834 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
838 void UsbCloseDeviceFunction::AsyncWorkStart() {
839 scoped_refptr
<UsbDeviceHandle
> device_handle
=
840 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
841 if (!device_handle
.get())
844 device_handle
->Close();
845 RemoveUsbDeviceResource(parameters_
->handle
.handle
);
846 AsyncWorkCompleted();
849 UsbClaimInterfaceFunction::UsbClaimInterfaceFunction() {
852 UsbClaimInterfaceFunction::~UsbClaimInterfaceFunction() {
855 bool UsbClaimInterfaceFunction::Prepare() {
856 parameters_
= ClaimInterface::Params::Create(*args_
);
857 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
861 void UsbClaimInterfaceFunction::AsyncWorkStart() {
862 scoped_refptr
<UsbDeviceHandle
> device_handle
=
863 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
864 if (!device_handle
.get())
867 bool success
= device_handle
->ClaimInterface(parameters_
->interface_number
);
870 SetError(kErrorCannotClaimInterface
);
871 AsyncWorkCompleted();
874 UsbReleaseInterfaceFunction::UsbReleaseInterfaceFunction() {
877 UsbReleaseInterfaceFunction::~UsbReleaseInterfaceFunction() {
880 bool UsbReleaseInterfaceFunction::Prepare() {
881 parameters_
= ReleaseInterface::Params::Create(*args_
);
882 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
886 void UsbReleaseInterfaceFunction::AsyncWorkStart() {
887 scoped_refptr
<UsbDeviceHandle
> device_handle
=
888 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
889 if (!device_handle
.get())
892 bool success
= device_handle
->ReleaseInterface(parameters_
->interface_number
);
894 SetError(kErrorCannotReleaseInterface
);
895 AsyncWorkCompleted();
898 UsbSetInterfaceAlternateSettingFunction::
899 UsbSetInterfaceAlternateSettingFunction() {
902 UsbSetInterfaceAlternateSettingFunction::
903 ~UsbSetInterfaceAlternateSettingFunction() {
906 bool UsbSetInterfaceAlternateSettingFunction::Prepare() {
907 parameters_
= SetInterfaceAlternateSetting::Params::Create(*args_
);
908 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
912 void UsbSetInterfaceAlternateSettingFunction::AsyncWorkStart() {
913 scoped_refptr
<UsbDeviceHandle
> device_handle
=
914 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
915 if (!device_handle
.get())
918 bool success
= device_handle
->SetInterfaceAlternateSetting(
919 parameters_
->interface_number
, parameters_
->alternate_setting
);
921 SetError(kErrorCannotSetInterfaceAlternateSetting
);
923 AsyncWorkCompleted();
926 UsbControlTransferFunction::UsbControlTransferFunction() {
929 UsbControlTransferFunction::~UsbControlTransferFunction() {
932 bool UsbControlTransferFunction::Prepare() {
933 parameters_
= ControlTransfer::Params::Create(*args_
);
934 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
938 void UsbControlTransferFunction::AsyncWorkStart() {
939 scoped_refptr
<UsbDeviceHandle
> device_handle
=
940 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
941 if (!device_handle
.get())
944 const ControlTransferInfo
& transfer
= parameters_
->transfer_info
;
946 UsbEndpointDirection direction
;
947 UsbDeviceHandle::TransferRequestType request_type
;
948 UsbDeviceHandle::TransferRecipient recipient
;
951 if (!ConvertDirectionSafely(transfer
.direction
, &direction
) ||
952 !ConvertRequestTypeSafely(transfer
.request_type
, &request_type
) ||
953 !ConvertRecipientSafely(transfer
.recipient
, &recipient
)) {
954 AsyncWorkCompleted();
958 if (!GetTransferSize(transfer
, &size
)) {
959 CompleteWithError(kErrorInvalidTransferLength
);
963 scoped_refptr
<net::IOBuffer
> buffer
=
964 CreateBufferForTransfer(transfer
, direction
, size
);
966 CompleteWithError(kErrorMalformedParameters
);
970 device_handle
->ControlTransfer(
980 base::Bind(&UsbControlTransferFunction::OnCompleted
, this));
983 UsbBulkTransferFunction::UsbBulkTransferFunction() {
986 UsbBulkTransferFunction::~UsbBulkTransferFunction() {
989 bool UsbBulkTransferFunction::Prepare() {
990 parameters_
= BulkTransfer::Params::Create(*args_
);
991 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
995 void UsbBulkTransferFunction::AsyncWorkStart() {
996 scoped_refptr
<UsbDeviceHandle
> device_handle
=
997 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
998 if (!device_handle
.get())
1001 const GenericTransferInfo
& transfer
= parameters_
->transfer_info
;
1003 UsbEndpointDirection direction
;
1006 if (!ConvertDirectionSafely(transfer
.direction
, &direction
)) {
1007 AsyncWorkCompleted();
1011 if (!GetTransferSize(transfer
, &size
)) {
1012 CompleteWithError(kErrorInvalidTransferLength
);
1016 scoped_refptr
<net::IOBuffer
> buffer
=
1017 CreateBufferForTransfer(transfer
, direction
, size
);
1018 if (!buffer
.get()) {
1019 CompleteWithError(kErrorMalformedParameters
);
1023 device_handle
->BulkTransfer(
1029 base::Bind(&UsbBulkTransferFunction::OnCompleted
, this));
1032 UsbInterruptTransferFunction::UsbInterruptTransferFunction() {
1035 UsbInterruptTransferFunction::~UsbInterruptTransferFunction() {
1038 bool UsbInterruptTransferFunction::Prepare() {
1039 parameters_
= InterruptTransfer::Params::Create(*args_
);
1040 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
1044 void UsbInterruptTransferFunction::AsyncWorkStart() {
1045 scoped_refptr
<UsbDeviceHandle
> device_handle
=
1046 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
1047 if (!device_handle
.get())
1050 const GenericTransferInfo
& transfer
= parameters_
->transfer_info
;
1052 UsbEndpointDirection direction
;
1055 if (!ConvertDirectionSafely(transfer
.direction
, &direction
)) {
1056 AsyncWorkCompleted();
1060 if (!GetTransferSize(transfer
, &size
)) {
1061 CompleteWithError(kErrorInvalidTransferLength
);
1065 scoped_refptr
<net::IOBuffer
> buffer
=
1066 CreateBufferForTransfer(transfer
, direction
, size
);
1067 if (!buffer
.get()) {
1068 CompleteWithError(kErrorMalformedParameters
);
1072 device_handle
->InterruptTransfer(
1078 base::Bind(&UsbInterruptTransferFunction::OnCompleted
, this));
1081 UsbIsochronousTransferFunction::UsbIsochronousTransferFunction() {
1084 UsbIsochronousTransferFunction::~UsbIsochronousTransferFunction() {
1087 bool UsbIsochronousTransferFunction::Prepare() {
1088 parameters_
= IsochronousTransfer::Params::Create(*args_
);
1089 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
1093 void UsbIsochronousTransferFunction::AsyncWorkStart() {
1094 scoped_refptr
<UsbDeviceHandle
> device_handle
=
1095 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
1096 if (!device_handle
.get())
1099 const IsochronousTransferInfo
& transfer
= parameters_
->transfer_info
;
1100 const GenericTransferInfo
& generic_transfer
= transfer
.transfer_info
;
1103 UsbEndpointDirection direction
;
1105 if (!ConvertDirectionSafely(generic_transfer
.direction
, &direction
)) {
1106 AsyncWorkCompleted();
1109 if (!GetTransferSize(generic_transfer
, &size
)) {
1110 CompleteWithError(kErrorInvalidTransferLength
);
1113 if (transfer
.packets
< 0 || transfer
.packets
>= kMaxPackets
) {
1114 CompleteWithError(kErrorInvalidNumberOfPackets
);
1117 unsigned int packets
= transfer
.packets
;
1118 if (transfer
.packet_length
< 0 ||
1119 transfer
.packet_length
>= kMaxPacketLength
) {
1120 CompleteWithError(kErrorInvalidPacketLength
);
1123 unsigned int packet_length
= transfer
.packet_length
;
1124 const uint64 total_length
= packets
* packet_length
;
1125 if (packets
> size
|| total_length
> size
) {
1126 CompleteWithError(kErrorTransferLength
);
1130 scoped_refptr
<net::IOBuffer
> buffer
=
1131 CreateBufferForTransfer(generic_transfer
, direction
, size
);
1132 if (!buffer
.get()) {
1133 CompleteWithError(kErrorMalformedParameters
);
1137 device_handle
->IsochronousTransfer(
1139 generic_transfer
.endpoint
,
1145 base::Bind(&UsbIsochronousTransferFunction::OnCompleted
, this));
1148 UsbResetDeviceFunction::UsbResetDeviceFunction() {
1151 UsbResetDeviceFunction::~UsbResetDeviceFunction() {
1154 bool UsbResetDeviceFunction::Prepare() {
1155 parameters_
= ResetDevice::Params::Create(*args_
);
1156 EXTENSION_FUNCTION_VALIDATE(parameters_
.get());
1160 void UsbResetDeviceFunction::AsyncWorkStart() {
1161 scoped_refptr
<UsbDeviceHandle
> device_handle
=
1162 GetDeviceHandleOrCompleteWithError(parameters_
->handle
);
1163 if (!device_handle
.get())
1166 bool success
= device_handle
->ResetDevice();
1168 device_handle
->Close();
1169 RemoveUsbDeviceResource(parameters_
->handle
.handle
);
1170 SetResult(new base::FundamentalValue(false));
1171 CompleteWithError(kErrorResetDevice
);
1175 SetResult(new base::FundamentalValue(true));
1176 AsyncWorkCompleted();
1179 } // namespace extensions