Index: chrome/browser/extensions/api/usb/usb_api.cc |
diff --git a/chrome/browser/extensions/api/usb/usb_api.cc b/chrome/browser/extensions/api/usb/usb_api.cc |
index c8ec84863937b6b863acd357aac00f0bcdc081b6..e6ca32719227234f0c338b134e3f11198121cd34 100644 |
--- a/chrome/browser/extensions/api/usb/usb_api.cc |
+++ b/chrome/browser/extensions/api/usb/usb_api.cc |
@@ -8,6 +8,7 @@ |
#include <vector> |
#include "base/memory/scoped_ptr.h" |
+#include "base/message_loop/message_loop_proxy.h" |
#include "chrome/browser/extensions/api/usb/usb_device_resource.h" |
#include "chrome/browser/extensions/extension_system.h" |
#include "chrome/browser/profiles/profile.h" |
@@ -17,24 +18,27 @@ |
#include "chrome/common/extensions/permissions/permissions_data.h" |
#include "chrome/common/extensions/permissions/usb_device_permission.h" |
-namespace BulkTransfer = extensions::api::usb::BulkTransfer; |
-namespace ClaimInterface = extensions::api::usb::ClaimInterface; |
-namespace ListInterfaces = extensions::api::usb::ListInterfaces; |
-namespace CloseDevice = extensions::api::usb::CloseDevice; |
-namespace ControlTransfer = extensions::api::usb::ControlTransfer; |
-namespace FindDevices = extensions::api::usb::FindDevices; |
-namespace InterruptTransfer = extensions::api::usb::InterruptTransfer; |
-namespace IsochronousTransfer = extensions::api::usb::IsochronousTransfer; |
-namespace ReleaseInterface = extensions::api::usb::ReleaseInterface; |
-namespace ResetDevice = extensions::api::usb::ResetDevice; |
-namespace SetInterfaceAlternateSetting = |
- extensions::api::usb::SetInterfaceAlternateSetting; |
namespace usb = extensions::api::usb; |
+namespace BulkTransfer = usb::BulkTransfer; |
+namespace ClaimInterface = usb::ClaimInterface; |
+namespace CloseDevice = usb::CloseDevice; |
+namespace ControlTransfer = usb::ControlTransfer; |
+namespace FindDevices = usb::FindDevices; |
+namespace GetDevices = usb::GetDevices; |
+namespace InterruptTransfer = usb::InterruptTransfer; |
+namespace IsochronousTransfer = usb::IsochronousTransfer; |
+namespace ListInterfaces = usb::ListInterfaces; |
+namespace OpenDevice = usb::OpenDevice; |
+namespace ReleaseInterface = usb::ReleaseInterface; |
+namespace RequestAccess = usb::RequestAccess; |
+namespace ResetDevice = usb::ResetDevice; |
+namespace SetInterfaceAlternateSetting = usb::SetInterfaceAlternateSetting; |
using content::BrowserThread; |
using std::string; |
using std::vector; |
using usb::ControlTransferInfo; |
+using usb::ConnectionHandle; |
using usb::Device; |
using usb::Direction; |
using usb::EndpointDescriptor; |
@@ -47,52 +51,56 @@ using usb::SynchronizationType; |
using usb::TransferType; |
using usb::UsageType; |
+typedef std::vector<scoped_refptr<UsbDevice> > DeviceVector; |
+typedef scoped_ptr<DeviceVector> ScopedDeviceVector; |
+ |
namespace { |
-static const char kDataKey[] = "data"; |
-static const char kResultCodeKey[] = "resultCode"; |
- |
-static const char kErrorCancelled[] = "Transfer was cancelled."; |
-static const char kErrorDisconnect[] = "Device disconnected."; |
-static const char kErrorGeneric[] = "Transfer failed."; |
-static const char kErrorOverflow[] = "Inbound transfer overflow."; |
-static const char kErrorStalled[] = "Transfer stalled."; |
-static const char kErrorTimeout[] = "Transfer timed out."; |
-static const char kErrorTransferLength[] = "Transfer length is insufficient."; |
- |
-static const char kErrorCannotListInterfaces[] = "Error listing interfaces."; |
-static const char kErrorCannotClaimInterface[] = "Error claiming interface."; |
-static const char kErrorCannotReleaseInterface[] = "Error releasing interface."; |
-static const char kErrorCannotSetInterfaceAlternateSetting[] = |
+const char kDataKey[] = "data"; |
+const char kResultCodeKey[] = "resultCode"; |
+ |
+const char kErrorOpen[] = "Failed to open device."; |
+const char kErrorCancelled[] = "Transfer was cancelled."; |
+const char kErrorDisconnect[] = "Device disconnected."; |
+const char kErrorGeneric[] = "Transfer failed."; |
+const char kErrorNotSupported[] = "Not supported on this platform."; |
+const char kErrorOverflow[] = "Inbound transfer overflow."; |
+const char kErrorStalled[] = "Transfer stalled."; |
+const char kErrorTimeout[] = "Transfer timed out."; |
+const char kErrorTransferLength[] = "Transfer length is insufficient."; |
+ |
+const char kErrorCannotListInterfaces[] = "Error listing interfaces."; |
+const char kErrorCannotClaimInterface[] = "Error claiming interface."; |
+const char kErrorCannotReleaseInterface[] = "Error releasing interface."; |
+const char kErrorCannotSetInterfaceAlternateSetting[] = |
"Error setting alternate interface setting."; |
-static const char kErrorConvertDirection[] = "Invalid transfer direction."; |
-static const char kErrorConvertRecipient[] = "Invalid transfer recipient."; |
-static const char kErrorConvertRequestType[] = "Invalid request type."; |
-static const char kErrorConvertSynchronizationType[] = |
- "Invalid synchronization type"; |
-static const char kErrorConvertTransferType[] = "Invalid endpoint type."; |
-static const char kErrorConvertUsageType[] = "Invalid usage type."; |
-static const char kErrorMalformedParameters[] = "Error parsing parameters."; |
-static const char kErrorNoDevice[] = "No such device."; |
-static const char kErrorPermissionDenied[] = |
+const char kErrorConvertDirection[] = "Invalid transfer direction."; |
+const char kErrorConvertRecipient[] = "Invalid transfer recipient."; |
+const char kErrorConvertRequestType[] = "Invalid request type."; |
+const char kErrorConvertSynchronizationType[] = "Invalid synchronization type"; |
+const char kErrorConvertTransferType[] = "Invalid endpoint type."; |
+const char kErrorConvertUsageType[] = "Invalid usage type."; |
+const char kErrorMalformedParameters[] = "Error parsing parameters."; |
+const char kErrorNoDevice[] = "No such device."; |
+const char kErrorPermissionDenied[] = |
"Permission to access device was denied"; |
-static const char kErrorInvalidTransferLength[] = "Transfer length must be a " |
- "positive number less than 104,857,600."; |
-static const char kErrorInvalidNumberOfPackets[] = "Number of packets must be " |
- "a positive number less than 4,194,304."; |
-static const char kErrorInvalidPacketLength[] = "Packet length must be a " |
+const char kErrorInvalidTransferLength[] = |
+ "Transfer length must be a positive number less than 104,857,600."; |
+const char kErrorInvalidNumberOfPackets[] = |
+ "Number of packets must be a positive number less than 4,194,304."; |
+const char kErrorInvalidPacketLength[] = "Packet length must be a " |
"positive number less than 65,536."; |
-static const char kErrorResetDevice[] = |
+const char kErrorResetDevice[] = |
"Error resetting the device. The device has been closed."; |
-static const size_t kMaxTransferLength = 100 * 1024 * 1024; |
-static const int kMaxPackets = 4 * 1024 * 1024; |
-static const int kMaxPacketLength = 64 * 1024; |
+const size_t kMaxTransferLength = 100 * 1024 * 1024; |
+const int kMaxPackets = 4 * 1024 * 1024; |
+const int kMaxPacketLength = 64 * 1024; |
-static UsbDevice* g_device_for_test = NULL; |
+UsbDevice* g_device_for_test = NULL; |
-static bool ConvertDirectionToApi(const UsbEndpointDirection& input, |
- Direction* output) { |
+bool ConvertDirectionToApi(const UsbEndpointDirection& input, |
+ Direction* output) { |
switch (input) { |
case USB_DIRECTION_INBOUND: |
*output = usb::DIRECTION_IN; |
@@ -106,9 +114,8 @@ static bool ConvertDirectionToApi(const UsbEndpointDirection& input, |
} |
} |
-static bool ConvertSynchronizationTypeToApi( |
- const UsbSynchronizationType& input, |
- extensions::api::usb::SynchronizationType* output) { |
+bool ConvertSynchronizationTypeToApi(const UsbSynchronizationType& input, |
+ usb::SynchronizationType* output) { |
switch (input) { |
case USB_SYNCHRONIZATION_NONE: |
*output = usb::SYNCHRONIZATION_TYPE_NONE; |
@@ -128,9 +135,9 @@ static bool ConvertSynchronizationTypeToApi( |
} |
} |
-static bool ConvertTransferTypeToApi( |
+bool ConvertTransferTypeToApi( |
const UsbTransferType& input, |
- extensions::api::usb::TransferType* output) { |
+ usb::TransferType* output) { |
switch (input) { |
case USB_TRANSFER_CONTROL: |
*output = usb::TRANSFER_TYPE_CONTROL; |
@@ -150,8 +157,7 @@ static bool ConvertTransferTypeToApi( |
} |
} |
-static bool ConvertUsageTypeToApi(const UsbUsageType& input, |
- extensions::api::usb::UsageType* output) { |
+bool ConvertUsageTypeToApi(const UsbUsageType& input, usb::UsageType* output) { |
switch (input) { |
case USB_USAGE_DATA: |
*output = usb::USAGE_TYPE_DATA; |
@@ -168,8 +174,8 @@ static bool ConvertUsageTypeToApi(const UsbUsageType& input, |
} |
} |
-static bool ConvertDirection(const Direction& input, |
- UsbEndpointDirection* output) { |
+bool ConvertDirection(const Direction& input, |
+ UsbEndpointDirection* output) { |
switch (input) { |
case usb::DIRECTION_IN: |
*output = USB_DIRECTION_INBOUND; |
@@ -183,8 +189,8 @@ static bool ConvertDirection(const Direction& input, |
} |
} |
-static bool ConvertRequestType(const RequestType& input, |
- UsbDeviceHandle::TransferRequestType* output) { |
+bool ConvertRequestType(const RequestType& input, |
+ UsbDeviceHandle::TransferRequestType* output) { |
switch (input) { |
case usb::REQUEST_TYPE_STANDARD: |
*output = UsbDeviceHandle::STANDARD; |
@@ -204,8 +210,8 @@ static bool ConvertRequestType(const RequestType& input, |
} |
} |
-static bool ConvertRecipient(const Recipient& input, |
- UsbDeviceHandle::TransferRecipient* output) { |
+bool ConvertRecipient(const Recipient& input, |
+ UsbDeviceHandle::TransferRecipient* output) { |
switch (input) { |
case usb::RECIPIENT_DEVICE: |
*output = UsbDeviceHandle::DEVICE; |
@@ -226,7 +232,7 @@ static bool ConvertRecipient(const Recipient& input, |
} |
template<class T> |
-static bool GetTransferSize(const T& input, size_t* output) { |
+bool GetTransferSize(const T& input, size_t* output) { |
if (input.direction == usb::DIRECTION_IN) { |
const int* length = input.length.get(); |
if (length && *length >= 0 && |
@@ -244,7 +250,7 @@ static bool GetTransferSize(const T& input, size_t* output) { |
} |
template<class T> |
-static scoped_refptr<net::IOBuffer> CreateBufferForTransfer( |
+scoped_refptr<net::IOBuffer> CreateBufferForTransfer( |
const T& input, UsbEndpointDirection direction, size_t size) { |
if (size >= kMaxTransferLength) |
@@ -268,8 +274,7 @@ static scoped_refptr<net::IOBuffer> CreateBufferForTransfer( |
return NULL; |
} |
-static const char* ConvertTransferStatusToErrorString( |
- const UsbTransferStatus status) { |
+const char* ConvertTransferStatusToErrorString(const UsbTransferStatus status) { |
switch (status) { |
case USB_TRANSFER_COMPLETED: |
return ""; |
@@ -293,7 +298,37 @@ static const char* ConvertTransferStatusToErrorString( |
} |
} |
-static base::DictionaryValue* CreateTransferInfo( |
+#if defined(OS_CHROMEOS) |
+void RequestUsbDevicesAccessHelper( |
+ std::vector<scoped_refptr<UsbDevice> >* devices, |
+ std::vector<scoped_refptr<UsbDevice> >::iterator i, |
+ int interface_id, |
+ const base::Closure& callback, |
+ bool success) { |
+ if (success) { |
+ ++i; |
+ } else { |
+ i = devices->erase(i); |
+ } |
+ if (i == devices->end()) { |
+ callback.Run(); |
+ return; |
+ } |
+ (*i)->RequestUsbAcess(interface_id, |
+ base::Bind(RequestUsbDevicesAccessHelper, devices, i, |
+ interface_id, callback)); |
+} |
+ |
+void RequestUsbDevicesAccess( |
+ std::vector<scoped_refptr<UsbDevice> >* devices, |
+ int interface_id, |
+ const base::Closure& callback) { |
+ RequestUsbDevicesAccessHelper(devices, devices->begin(), interface_id, |
+ callback, true); |
+} |
+#endif // OS_CHROMEOS |
+ |
+base::DictionaryValue* CreateTransferInfo( |
UsbTransferStatus status, |
scoped_refptr<net::IOBuffer> data, |
size_t length) { |
@@ -304,18 +339,30 @@ static base::DictionaryValue* CreateTransferInfo( |
return result; |
} |
-static base::Value* PopulateDevice(int handle, int vendor_id, int product_id) { |
- Device device; |
- device.handle = handle; |
- device.vendor_id = vendor_id; |
- device.product_id = product_id; |
- return device.ToValue().release(); |
+base::Value* PopulateConnectionHandle(int handle, int vendor_id, |
+ int product_id) { |
+ ConnectionHandle result; |
+ result.handle = handle; |
+ result.vendor_id = vendor_id; |
+ result.product_id = product_id; |
+ return result.ToValue().release(); |
+} |
+ |
+base::Value* PopulateDevice(UsbDevice* device) { |
+ Device result; |
+ result.device = device->unique_id(); |
+ result.vendor_id = device->vendor_id(); |
+ result.product_id = device->product_id(); |
+ return result.ToValue().release(); |
} |
-static base::Value* PopulateInterfaceDescriptor(int interface_number, |
- int alternate_setting, int interface_class, int interface_subclass, |
- int interface_protocol, |
- std::vector<linked_ptr<EndpointDescriptor> >* endpoints) { |
+base::Value* PopulateInterfaceDescriptor( |
+ int interface_number, |
+ int alternate_setting, |
+ int interface_class, |
+ int interface_subclass, |
+ int interface_protocol, |
+ std::vector<linked_ptr<EndpointDescriptor> >* endpoints) { |
InterfaceDescriptor descriptor; |
descriptor.interface_number = interface_number; |
descriptor.alternate_setting = alternate_setting; |
@@ -347,9 +394,62 @@ bool UsbAsyncApiFunction::Respond() { |
return error_.empty(); |
} |
-UsbDeviceResource* UsbAsyncApiFunction::GetUsbDeviceResource( |
- int api_resource_id) { |
- return manager_->Get(extension_->id(), api_resource_id); |
+scoped_refptr<UsbDevice> |
+UsbAsyncApiFunction::GetDeviceOrOrCompleteWithError( |
+ const Device& input_device) { |
+ if (g_device_for_test) |
+ return g_device_for_test; |
+ |
+ const uint16_t vendor_id = input_device.vendor_id; |
+ const uint16_t product_id = input_device.product_id; |
+ UsbDevicePermission::CheckParam param( |
+ vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE); |
+ if (!PermissionsData::CheckAPIPermissionWithParam( |
+ GetExtension(), APIPermission::kUsbDevice, ¶m)) { |
+ LOG(WARNING) << "Insufficient permissions to access device."; |
+ CompleteWithError(kErrorPermissionDenied); |
+ return NULL; |
+ } |
+ |
+ UsbService* service = UsbService::GetInstance(); |
+ scoped_refptr<UsbDevice> device; |
+ |
+ device = service->GetDeviceById(input_device.device); |
+ |
+ if (!device) { |
+ CompleteWithError(kErrorNoDevice); |
+ return NULL; |
+ } |
+ |
+ if (device->vendor_id() != input_device.vendor_id || |
+ device->product_id() != input_device.product_id) { |
+ // Must act as if there is no such a device. |
+ // Otherwise can be used to finger print unauthorized devices. |
+ CompleteWithError(kErrorNoDevice); |
+ return NULL; |
+ } |
+ |
+ return device; |
+} |
+ |
+scoped_refptr<UsbDeviceHandle> |
+UsbAsyncApiFunction::GetDeviceHandleOrCompleteWithError( |
+ const ConnectionHandle& input_device_handle) { |
+ UsbDeviceResource* resource = |
+ manager_->Get(extension_->id(), input_device_handle.handle); |
+ if (!resource) { |
+ CompleteWithError(kErrorNoDevice); |
+ return NULL; |
+ } |
+ if (resource->device()->device()->vendor_id() != |
+ input_device_handle.vendor_id || |
+ resource->device()->device()->product_id() != |
+ input_device_handle.product_id) { |
+ CompleteWithError(kErrorNoDevice); |
+ return NULL; |
+ } |
+ |
+ return resource->device(); |
} |
void UsbAsyncApiFunction::RemoveUsbDeviceResource(int api_resource_id) { |
@@ -403,10 +503,6 @@ UsbFindDevicesFunction::UsbFindDevicesFunction() {} |
UsbFindDevicesFunction::~UsbFindDevicesFunction() {} |
-void UsbFindDevicesFunction::SetDeviceForTest(UsbDevice* device) { |
- g_device_for_test = device; |
-} |
- |
bool UsbFindDevicesFunction::Prepare() { |
parameters_ = FindDevices::Params::Create(*args_); |
EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
@@ -414,16 +510,15 @@ bool UsbFindDevicesFunction::Prepare() { |
} |
void UsbFindDevicesFunction::AsyncWorkStart() { |
- result_.reset(new base::ListValue()); |
+ scoped_ptr<base::ListValue> result(new base::ListValue()); |
if (g_device_for_test) { |
UsbDeviceResource* const resource = new UsbDeviceResource( |
extension_->id(), |
g_device_for_test->Open()); |
- Device device; |
- result_->Append(PopulateDevice(manager_->Add(resource), 0, 0)); |
- SetResult(result_.release()); |
+ result->Append(PopulateConnectionHandle(manager_->Add(resource), 0, 0)); |
+ SetResult(result.release()); |
AsyncWorkCompleted(); |
return; |
} |
@@ -442,14 +537,34 @@ void UsbFindDevicesFunction::AsyncWorkStart() { |
} |
UsbService *service = UsbService::GetInstance(); |
- service->FindDevices( |
- vendor_id, product_id, interface_id, |
- base::Bind(&UsbFindDevicesFunction::EnumerationCompletedFileThread, |
- this)); |
+ ScopedDeviceVector devices(new DeviceVector()); |
+ service->GetDevices(devices.get()); |
+ |
+ for (DeviceVector::iterator it = devices->begin(); |
+ it != devices->end();) { |
+ if ((*it)->vendor_id() != vendor_id || (*it)->product_id() != product_id) { |
+ it = devices->erase(it); |
+ } else { |
+ ++it; |
+ } |
+ } |
+ |
+#if defined(OS_CHROMEOS) |
+ if (parameters_->options.interface_id.get()) { |
+ int interface_id = *parameters_->options.interface_id.get(); |
+ RequestUsbDevicesAccess(devices.get(), interface_id, |
+ base::Bind(&UsbFindDevicesFunction::OpenDevices, |
+ this, |
+ base::Passed(devices.Pass()))); |
+ return; |
+ } |
+#endif // OS_CHROMEOS |
+ OpenDevices(devices.Pass()); |
} |
-void UsbFindDevicesFunction::EnumerationCompletedFileThread( |
- scoped_ptr<std::vector<scoped_refptr<UsbDevice> > > devices) { |
+void UsbFindDevicesFunction::OpenDevices(ScopedDeviceVector devices) { |
+ base::ListValue* result = new base::ListValue(); |
+ |
for (size_t i = 0; i < devices->size(); ++i) { |
scoped_refptr<UsbDeviceHandle> device_handle = |
devices->at(i)->Open(); |
@@ -462,12 +577,128 @@ void UsbFindDevicesFunction::EnumerationCompletedFileThread( |
UsbDeviceResource* const resource = |
new UsbDeviceResource(extension_->id(), device_handle); |
- result_->Append(PopulateDevice(manager_->Add(resource), |
- parameters_->options.vendor_id, |
- parameters_->options.product_id)); |
+ result->Append(PopulateConnectionHandle(manager_->Add(resource), |
+ parameters_->options.vendor_id, |
+ parameters_->options.product_id)); |
} |
- SetResult(result_.release()); |
+ SetResult(result); |
+ AsyncWorkCompleted(); |
+} |
+ |
+UsbGetDevicesFunction::UsbGetDevicesFunction() { |
+} |
+ |
+UsbGetDevicesFunction::~UsbGetDevicesFunction() { |
+} |
+ |
+void UsbGetDevicesFunction::SetDeviceForTest(UsbDevice* device) { |
+ g_device_for_test = device; |
+} |
+ |
+bool UsbGetDevicesFunction::Prepare() { |
+ parameters_ = GetDevices::Params::Create(*args_); |
+ EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
+ return true; |
+} |
+ |
+void UsbGetDevicesFunction::AsyncWorkStart() { |
+ scoped_ptr<base::ListValue> result(new base::ListValue()); |
+ |
+ if (g_device_for_test) { |
+ result->Append(PopulateDevice(g_device_for_test)); |
+ SetResult(result.release()); |
+ AsyncWorkCompleted(); |
+ return; |
+ } |
+ |
+ const uint16_t vendor_id = parameters_->options.vendor_id; |
+ const uint16_t product_id = parameters_->options.product_id; |
+ UsbDevicePermission::CheckParam param( |
+ vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE); |
+ if (!PermissionsData::CheckAPIPermissionWithParam( |
+ GetExtension(), APIPermission::kUsbDevice, ¶m)) { |
+ LOG(WARNING) << "Insufficient permissions to access device."; |
+ CompleteWithError(kErrorPermissionDenied); |
+ return; |
+ } |
+ |
+ UsbService* service = UsbService::GetInstance(); |
+ DeviceVector devices; |
+ service->GetDevices(&devices); |
+ |
+ for (DeviceVector::iterator it = devices.begin(); it != devices.end();) { |
+ if ((*it)->vendor_id() != vendor_id || (*it)->product_id() != product_id) { |
+ it = devices.erase(it); |
+ } else { |
+ ++it; |
+ } |
+ } |
+ |
+ for (size_t i = 0; i < devices.size(); ++i) { |
+ result->Append(PopulateDevice(devices[i].get())); |
+ } |
+ |
+ SetResult(result.release()); |
+ AsyncWorkCompleted(); |
+} |
+ |
+UsbRequestAccessFunction::UsbRequestAccessFunction() {} |
+ |
+UsbRequestAccessFunction::~UsbRequestAccessFunction() {} |
+ |
+bool UsbRequestAccessFunction::Prepare() { |
+ parameters_ = RequestAccess::Params::Create(*args_); |
+ EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
+ return true; |
+} |
+ |
+void UsbRequestAccessFunction::AsyncWorkStart() { |
+#if defined(OS_CHROMEOS) |
+ scoped_refptr<UsbDevice> device = |
+ GetDeviceOrOrCompleteWithError(parameters_->device); |
+ if (!device) return; |
+ |
+ device->RequestUsbAcess(parameters_->interface_id, |
+ base::Bind(&UsbRequestAccessFunction::OnCompleted, |
+ this)); |
+#else |
+ SetResult(new base::FundamentalValue(false)); |
+ CompleteWithError(kErrorNotSupported); |
+#endif // OS_CHROMEOS |
+} |
+ |
+void UsbRequestAccessFunction::OnCompleted(bool success) { |
+ SetResult(new base::FundamentalValue(success)); |
+ AsyncWorkCompleted(); |
+} |
+ |
+UsbOpenDeviceFunction::UsbOpenDeviceFunction() {} |
+ |
+UsbOpenDeviceFunction::~UsbOpenDeviceFunction() {} |
+ |
+bool UsbOpenDeviceFunction::Prepare() { |
+ parameters_ = OpenDevice::Params::Create(*args_); |
+ EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
+ return true; |
+} |
+ |
+void UsbOpenDeviceFunction::AsyncWorkStart() { |
+ scoped_refptr<UsbDevice> device = |
+ GetDeviceOrOrCompleteWithError(parameters_->device); |
+ if (!device) return; |
+ |
+ handle_ = device->Open(); |
+ if (!handle_) { |
+ SetError(kErrorOpen); |
+ AsyncWorkCompleted(); |
+ return; |
+ } |
+ |
+ SetResult(PopulateConnectionHandle( |
+ manager_->Add(new UsbDeviceResource(extension_->id(), handle_)), |
+ handle_->device()->vendor_id(), |
+ handle_->device()->product_id())); |
AsyncWorkCompleted(); |
} |
@@ -482,15 +713,12 @@ bool UsbListInterfacesFunction::Prepare() { |
} |
void UsbListInterfacesFunction::AsyncWorkStart() { |
- UsbDeviceResource* const resource = GetUsbDeviceResource( |
- parameters_->device.handle); |
- if (!resource) { |
- CompleteWithError(kErrorNoDevice); |
- return; |
- } |
+ scoped_refptr<UsbDeviceHandle> device_handle = |
+ GetDeviceHandleOrCompleteWithError(parameters_->handle); |
+ if (!device_handle) return; |
scoped_refptr<UsbConfigDescriptor> config = |
- resource->device()->device()->ListInterfaces(); |
+ device_handle->device()->ListInterfaces(); |
if (!config) { |
SetError(kErrorCannotListInterfaces); |
@@ -560,7 +788,7 @@ void UsbListInterfacesFunction::AsyncWorkStart() { |
bool UsbListInterfacesFunction::ConvertDirectionSafely( |
const UsbEndpointDirection& input, |
- extensions::api::usb::Direction* output) { |
+ usb::Direction* output) { |
const bool converted = ConvertDirectionToApi(input, output); |
if (!converted) |
SetError(kErrorConvertDirection); |
@@ -569,7 +797,7 @@ bool UsbListInterfacesFunction::ConvertDirectionSafely( |
bool UsbListInterfacesFunction::ConvertSynchronizationTypeSafely( |
const UsbSynchronizationType& input, |
- extensions::api::usb::SynchronizationType* output) { |
+ usb::SynchronizationType* output) { |
const bool converted = ConvertSynchronizationTypeToApi(input, output); |
if (!converted) |
SetError(kErrorConvertSynchronizationType); |
@@ -578,7 +806,7 @@ bool UsbListInterfacesFunction::ConvertSynchronizationTypeSafely( |
bool UsbListInterfacesFunction::ConvertTransferTypeSafely( |
const UsbTransferType& input, |
- extensions::api::usb::TransferType* output) { |
+ usb::TransferType* output) { |
const bool converted = ConvertTransferTypeToApi(input, output); |
if (!converted) |
SetError(kErrorConvertTransferType); |
@@ -587,7 +815,7 @@ bool UsbListInterfacesFunction::ConvertTransferTypeSafely( |
bool UsbListInterfacesFunction::ConvertUsageTypeSafely( |
const UsbUsageType& input, |
- extensions::api::usb::UsageType* output) { |
+ usb::UsageType* output) { |
const bool converted = ConvertUsageTypeToApi(input, output); |
if (!converted) |
SetError(kErrorConvertUsageType); |
@@ -605,15 +833,12 @@ bool UsbCloseDeviceFunction::Prepare() { |
} |
void UsbCloseDeviceFunction::AsyncWorkStart() { |
- UsbDeviceResource* const resource = GetUsbDeviceResource( |
- parameters_->device.handle); |
- if (!resource) { |
- CompleteWithError(kErrorNoDevice); |
- return; |
- } |
+ scoped_refptr<UsbDeviceHandle> device_handle = |
+ GetDeviceHandleOrCompleteWithError(parameters_->handle); |
+ if (!device_handle) return; |
- resource->device()->Close(); |
- RemoveUsbDeviceResource(parameters_->device.handle); |
+ device_handle->Close(); |
+ RemoveUsbDeviceResource(parameters_->handle.handle); |
AsyncWorkCompleted(); |
} |
@@ -628,15 +853,11 @@ bool UsbClaimInterfaceFunction::Prepare() { |
} |
void UsbClaimInterfaceFunction::AsyncWorkStart() { |
- UsbDeviceResource* resource = |
- GetUsbDeviceResource(parameters_->device.handle); |
- if (!resource) { |
- CompleteWithError(kErrorNoDevice); |
- return; |
- } |
+ scoped_refptr<UsbDeviceHandle> device_handle = |
+ GetDeviceHandleOrCompleteWithError(parameters_->handle); |
+ if (!device_handle) return; |
- bool success = |
- resource->device()->ClaimInterface(parameters_->interface_number); |
+ bool success = device_handle->ClaimInterface(parameters_->interface_number); |
if (!success) |
SetError(kErrorCannotClaimInterface); |
@@ -654,14 +875,11 @@ bool UsbReleaseInterfaceFunction::Prepare() { |
} |
void UsbReleaseInterfaceFunction::AsyncWorkStart() { |
- UsbDeviceResource* resource = |
- GetUsbDeviceResource(parameters_->device.handle); |
- if (!resource) { |
- CompleteWithError(kErrorNoDevice); |
- return; |
- } |
- bool success = |
- resource->device()->ReleaseInterface(parameters_->interface_number); |
+ scoped_refptr<UsbDeviceHandle> device_handle = |
+ GetDeviceHandleOrCompleteWithError(parameters_->handle); |
+ if (!device_handle) return; |
+ |
+ bool success = device_handle->ReleaseInterface(parameters_->interface_number); |
if (!success) |
SetError(kErrorCannotReleaseInterface); |
AsyncWorkCompleted(); |
@@ -680,14 +898,11 @@ bool UsbSetInterfaceAlternateSettingFunction::Prepare() { |
} |
void UsbSetInterfaceAlternateSettingFunction::AsyncWorkStart() { |
- UsbDeviceResource* resource = |
- GetUsbDeviceResource(parameters_->device.handle); |
- if (!resource) { |
- CompleteWithError(kErrorNoDevice); |
- return; |
- } |
+ scoped_refptr<UsbDeviceHandle> device_handle = |
+ GetDeviceHandleOrCompleteWithError(parameters_->handle); |
+ if (!device_handle) return; |
- bool success = resource->device()->SetInterfaceAlternateSetting( |
+ bool success = device_handle->SetInterfaceAlternateSetting( |
parameters_->interface_number, |
parameters_->alternate_setting); |
if (!success) |
@@ -707,12 +922,9 @@ bool UsbControlTransferFunction::Prepare() { |
} |
void UsbControlTransferFunction::AsyncWorkStart() { |
- UsbDeviceResource* const resource = GetUsbDeviceResource( |
- parameters_->device.handle); |
- if (!resource) { |
- CompleteWithError(kErrorNoDevice); |
- return; |
- } |
+ scoped_refptr<UsbDeviceHandle> device_handle = |
+ GetDeviceHandleOrCompleteWithError(parameters_->handle); |
+ if (!device_handle) return; |
const ControlTransferInfo& transfer = parameters_->transfer_info; |
@@ -740,7 +952,7 @@ void UsbControlTransferFunction::AsyncWorkStart() { |
return; |
} |
- resource->device()->ControlTransfer( |
+ device_handle->ControlTransfer( |
direction, |
request_type, |
recipient, |
@@ -764,12 +976,9 @@ bool UsbBulkTransferFunction::Prepare() { |
} |
void UsbBulkTransferFunction::AsyncWorkStart() { |
- UsbDeviceResource* const resource = GetUsbDeviceResource( |
- parameters_->device.handle); |
- if (!resource) { |
- CompleteWithError(kErrorNoDevice); |
- return; |
- } |
+ scoped_refptr<UsbDeviceHandle> device_handle = |
+ GetDeviceHandleOrCompleteWithError(parameters_->handle); |
+ if (!device_handle) return; |
const GenericTransferInfo& transfer = parameters_->transfer_info; |
@@ -793,13 +1002,13 @@ void UsbBulkTransferFunction::AsyncWorkStart() { |
return; |
} |
- resource->device() |
- ->BulkTransfer(direction, |
- transfer.endpoint, |
- buffer.get(), |
- size, |
- 0, |
- base::Bind(&UsbBulkTransferFunction::OnCompleted, this)); |
+ device_handle->BulkTransfer( |
+ direction, |
+ transfer.endpoint, |
+ buffer.get(), |
+ size, |
+ 0, |
+ base::Bind(&UsbBulkTransferFunction::OnCompleted, this)); |
} |
UsbInterruptTransferFunction::UsbInterruptTransferFunction() {} |
@@ -813,12 +1022,9 @@ bool UsbInterruptTransferFunction::Prepare() { |
} |
void UsbInterruptTransferFunction::AsyncWorkStart() { |
- UsbDeviceResource* const resource = GetUsbDeviceResource( |
- parameters_->device.handle); |
- if (!resource) { |
- CompleteWithError(kErrorNoDevice); |
- return; |
- } |
+ scoped_refptr<UsbDeviceHandle> device_handle = |
+ GetDeviceHandleOrCompleteWithError(parameters_->handle); |
+ if (!device_handle) return; |
const GenericTransferInfo& transfer = parameters_->transfer_info; |
@@ -842,7 +1048,7 @@ void UsbInterruptTransferFunction::AsyncWorkStart() { |
return; |
} |
- resource->device()->InterruptTransfer( |
+ device_handle->InterruptTransfer( |
direction, |
transfer.endpoint, |
buffer.get(), |
@@ -862,12 +1068,9 @@ bool UsbIsochronousTransferFunction::Prepare() { |
} |
void UsbIsochronousTransferFunction::AsyncWorkStart() { |
- UsbDeviceResource* const resource = GetUsbDeviceResource( |
- parameters_->device.handle); |
- if (!resource) { |
- CompleteWithError(kErrorNoDevice); |
- return; |
- } |
+ scoped_refptr<UsbDeviceHandle> device_handle = |
+ GetDeviceHandleOrCompleteWithError(parameters_->handle); |
+ if (!device_handle) return; |
const IsochronousTransferInfo& transfer = parameters_->transfer_info; |
const GenericTransferInfo& generic_transfer = transfer.transfer_info; |
@@ -907,7 +1110,7 @@ void UsbIsochronousTransferFunction::AsyncWorkStart() { |
return; |
} |
- resource->device()->IsochronousTransfer( |
+ device_handle->IsochronousTransfer( |
direction, |
generic_transfer.endpoint, |
buffer.get(), |
@@ -929,28 +1132,19 @@ bool UsbResetDeviceFunction::Prepare() { |
} |
void UsbResetDeviceFunction::AsyncWorkStart() { |
- UsbDeviceResource* const resource = GetUsbDeviceResource( |
- parameters_->device.handle); |
- if (!resource) { |
- CompleteWithError(kErrorNoDevice); |
- return; |
- } |
+ scoped_refptr<UsbDeviceHandle> device_handle = |
+ GetDeviceHandleOrCompleteWithError(parameters_->handle); |
+ if (!device_handle) return; |
- bool success = resource->device()->ResetDevice(); |
+ bool success = device_handle->ResetDevice(); |
if (!success) { |
- UsbDeviceResource* const resource = GetUsbDeviceResource( |
- parameters_->device.handle); |
- if (!resource) { |
- CompleteWithError(kErrorNoDevice); |
- return; |
- } |
- resource->device()->Close(); |
- RemoveUsbDeviceResource(parameters_->device.handle); |
- SetError(kErrorResetDevice); |
+ device_handle->Close(); |
+ RemoveUsbDeviceResource(parameters_->handle.handle); |
SetResult(new base::FundamentalValue(false)); |
- AsyncWorkCompleted(); |
+ CompleteWithError(kErrorResetDevice); |
return; |
} |
+ |
SetResult(new base::FundamentalValue(true)); |
AsyncWorkCompleted(); |
} |