Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4047)

Unified Diff: chrome/browser/extensions/api/usb/usb_api.cc

Issue 22914023: Introducing chrome.usb.getDevices/openDevice API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@usb-interface
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 b6a54d2f0813aa6b2b01d075997268ea737cbba9..259ecfb63f8592cddffad274e84b21baf93d7c08 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,25 +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 ListInterfaces = usb::ListInterfaces;
+namespace CloseDevice = usb::CloseDevice;
+namespace ControlTransfer = usb::ControlTransfer;
+namespace FindDevices = usb::FindDevices;
+namespace InterruptTransfer = usb::InterruptTransfer;
+namespace IsochronousTransfer = usb::IsochronousTransfer;
+namespace ReleaseInterface = usb::ReleaseInterface;
+namespace ResetDevice = usb::ResetDevice;
+namespace SetInterfaceAlternateSetting = usb::SetInterfaceAlternateSetting;
+namespace GetDevices = usb::GetDevices;
+namespace OpenDevice = usb::OpenDevice;
asargent_no_longer_on_chrome 2013/08/22 21:06:13 nit: can you sort these alphabetically? It would m
Bei Zhang 2013/08/23 22:52:00 Done.
using content::BrowserThread;
using std::string;
using std::vector;
using usb::ControlTransferInfo;
using usb::Device;
+using usb::DeviceHandle;
using usb::Direction;
using usb::EndpointDescriptor;
using usb::GenericTransferInfo;
@@ -47,6 +50,8 @@ using usb::SynchronizationType;
using usb::TransferType;
using usb::UsageType;
+typedef scoped_ptr<std::vector<scoped_refptr<UsbDevice> > > ScopedDeviceVector;
+
namespace {
static const char kDataKey[] = "data";
@@ -84,6 +89,7 @@ static const char kErrorInvalidPacketLength[] = "Packet length must be a "
"positive number less than 65,536.";
static const char kErrorResetDevice[] =
"Error resetting the device. The device has been closed.";
+static const char kErrorOpen[] = "Failed to open device.";
static const size_t kMaxTransferLength = 100 * 1024 * 1024;
static const int kMaxPackets = 4 * 1024 * 1024;
@@ -304,18 +310,31 @@ 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* PopulateDeviceHandle(int resource_id,
+ int vendor_id,
+ int product_id) {
+ DeviceHandle result;
+ result.handle = resource_id;
+ result.vendor_id.reset(new int(vendor_id));
+ result.product_id.reset(new int(product_id));
+ return result.ToValue().release();
+}
+
+base::Value* PopulateDevice(UsbDevice* device) {
+ Device result;
+ result.device = device->unique_id();
+ result.vendor_id.reset(new int(device->vendor_id()));
+ result.product_id.reset(new int(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) {
asargent_no_longer_on_chrome 2013/08/22 21:06:13 nit: It looks like you removed the "static" linkag
Bei Zhang 2013/08/23 22:52:00 Done.
InterfaceDescriptor descriptor;
descriptor.interface_number = interface_number;
descriptor.alternate_setting = alternate_setting;
@@ -402,10 +421,6 @@ UsbFindDevicesFunction::UsbFindDevicesFunction() {}
UsbFindDevicesFunction::~UsbFindDevicesFunction() {}
-void UsbFindDevicesFunction::SetDeviceForTest(UsbDevice* device) {
- device_for_test_ = device;
-}
-
bool UsbFindDevicesFunction::Prepare() {
parameters_ = FindDevices::Params::Create(*args_);
EXTENSION_FUNCTION_VALIDATE(parameters_.get());
@@ -423,7 +438,7 @@ void UsbFindDevicesFunction::AsyncWorkStart() {
device_for_test_->Open());
Device device;
- result_->Append(PopulateDevice(manager_->Add(resource), 0, 0));
+ result_->Append(PopulateDeviceHandle(manager_->Add(resource), 0, 0));
SetResult(result_.release());
AsyncWorkCompleted();
return;
@@ -470,7 +485,7 @@ void UsbFindDevicesFunction::OnCompleted() {
UsbDeviceResource* const resource =
new UsbDeviceResource(extension_->id(), device_handle);
- result_->Append(PopulateDevice(manager_->Add(resource),
+ result_->Append(PopulateDeviceHandle(manager_->Add(resource),
parameters_->options.vendor_id,
parameters_->options.product_id));
}
@@ -479,6 +494,131 @@ void UsbFindDevicesFunction::OnCompleted() {
AsyncWorkCompleted();
}
+UsbGetDevicesFunction::UsbGetDevicesFunction() {
+}
+
+UsbGetDevicesFunction::~UsbGetDevicesFunction() {
+}
+
+void UsbGetDevicesFunction::SetDeviceForTest(UsbDevice* device) {
+ device_for_test_ = device;
+}
+
+bool UsbGetDevicesFunction::Prepare() {
+ parameters_ = GetDevices::Params::Create(*args_);
+ EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+ if (!device_for_test_)
+ set_work_thread_id(BrowserThread::FILE);
+ return true;
+}
+
+void UsbGetDevicesFunction::AsyncWorkStart() {
+ result_.reset(new base::ListValue());
+
+ if (device_for_test_) {
+ result_->Append(PopulateDevice(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;
+ int interface_id = parameters_->options.interface_id.get() ?
+ *parameters_->options.interface_id.get() :
+ UsbDevicePermissionData::ANY_INTERFACE;
+ UsbDevicePermission::CheckParam param(vendor_id, product_id, interface_id);
+ if (!PermissionsData::CheckAPIPermissionWithParam(
+ GetExtension(), APIPermission::kUsbDevice, &param)) {
+ LOG(WARNING) << "Insufficient permissions to access device.";
+ CompleteWithError(kErrorPermissionDenied);
+ return;
+ }
+
+ UsbService* service = UsbService::GetInstance();
+ service->FindDevices(
+ vendor_id,
+ product_id,
+ interface_id,
+ base::Bind(&UsbGetDevicesFunction::EnumerationCompletedFileThread, this));
+}
+
+void UsbGetDevicesFunction::EnumerationCompletedFileThread(
+ scoped_ptr<std::vector<scoped_refptr<UsbDevice> > > devices) {
+ for (size_t i = 0; i < devices->size(); ++i) {
+ result_->Append(PopulateDevice(devices->at(i).get()));
+ }
+
+ SetResult(result_.release());
+ AsyncWorkCompleted();
+}
+
+UsbOpenDeviceFunction::UsbOpenDeviceFunction() {}
+
+UsbOpenDeviceFunction::~UsbOpenDeviceFunction() {}
+
+bool UsbOpenDeviceFunction::Prepare() {
+ parameters_ = OpenDevice::Params::Create(*args_);
+ EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+ return true;
+}
+
+void UsbOpenDeviceFunction::AsyncWorkStart() {
+ BrowserThread::PostTask(BrowserThread::FILE,
+ FROM_HERE,
+ base::Bind(&UsbOpenDeviceFunction::OpenDeviceOnFile,
+ this));
+}
+
+void UsbOpenDeviceFunction::OpenDeviceOnFile() {
+ UsbService* service = UsbService::GetInstance();
+ scoped_refptr<UsbDevice> device;
+ if (device_for_test_)
+ device = device_for_test_;
+ else
+ device = service->GetDeviceById(parameters_->device.device);
+
+ if (!device) {
+ SetError(kErrorNoDevice);
+ AsyncWorkCompleted();
+ return;
+ }
+
+ if (!parameters_->device.vendor_id ||
+ *parameters_->device.vendor_id.get() != device->vendor_id()) {
+ SetError(kErrorOpen);
+ AsyncWorkCompleted();
+ return;
+ }
+
+ if (!parameters_->device.product_id ||
+ *parameters_->device.product_id.get() != device->product_id()) {
+ SetError(kErrorOpen);
+ AsyncWorkCompleted();
+ return;
+ }
+
+ handle_ = device->Open();
+ BrowserThread::PostTask(BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&UsbOpenDeviceFunction::OnCompleted,
+ this));
+}
+
+void UsbOpenDeviceFunction::OnCompleted() {
+ if (!handle_) {
+ SetError(kErrorOpen);
+ AsyncWorkCompleted();
+ return;
+ }
+
+ SetResult(PopulateDeviceHandle(
asargent_no_longer_on_chrome 2013/08/22 21:06:13 If the device handle could live on the FILE thread
Bei Zhang 2013/08/23 22:52:00 This is addressed by another CL. On 2013/08/22 21
+ manager_->Add(new UsbDeviceResource(extension_->id(), handle_)),
+ handle_->device()->vendor_id(),
+ handle_->device()->product_id()));
+ AsyncWorkCompleted();
+}
+
UsbListInterfacesFunction::UsbListInterfacesFunction() {}
UsbListInterfacesFunction::~UsbListInterfacesFunction() {}

Powered by Google App Engine
This is Rietveld 408576698