| 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();
|
| }
|
|
|