| Index: extensions/browser/api/usb/usb_api.cc
|
| diff --git a/extensions/browser/api/usb/usb_api.cc b/extensions/browser/api/usb/usb_api.cc
|
| index 20ed11752d5bb07569e85134c6ec14e0dd901385..71c345ebe20dd110e3814352206b55accec73436 100644
|
| --- a/extensions/browser/api/usb/usb_api.cc
|
| +++ b/extensions/browser/api/usb/usb_api.cc
|
| @@ -52,6 +52,7 @@ using usb::TransferType;
|
| using usb::UsageType;
|
| using usb_service::UsbConfigDescriptor;
|
| using usb_service::UsbDevice;
|
| +using usb_service::UsbDeviceFilter;
|
| using usb_service::UsbDeviceHandle;
|
| using usb_service::UsbEndpointDescriptor;
|
| using usb_service::UsbEndpointDirection;
|
| @@ -417,35 +418,51 @@ bool UsbAsyncApiFunction::Respond() {
|
| return error_.empty();
|
| }
|
|
|
| -scoped_refptr<UsbDevice> UsbAsyncApiFunction::GetDeviceOrOrCompleteWithError(
|
| - const Device& input_device) {
|
| - 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 (!extension()->permissions_data()->CheckAPIPermissionWithParam(
|
| - APIPermission::kUsbDevice, ¶m)) {
|
| - LOG(WARNING) << "Insufficient permissions to access device.";
|
| - CompleteWithError(kErrorPermissionDenied);
|
| - return NULL;
|
| +// static
|
| +void UsbAsyncApiFunction::CreateDeviceFilter(const usb::DeviceFilter& input,
|
| + UsbDeviceFilter* output) {
|
| + if (input.vendor_id) {
|
| + output->SetVendorId(*input.vendor_id);
|
| + }
|
| + if (input.product_id) {
|
| + output->SetProductId(*input.product_id);
|
| + }
|
| + if (input.interface_class) {
|
| + output->SetInterfaceClass(*input.interface_class);
|
| }
|
| + if (input.interface_subclass) {
|
| + output->SetInterfaceSubclass(*input.interface_subclass);
|
| + }
|
| + if (input.interface_protocol) {
|
| + output->SetInterfaceProtocol(*input.interface_protocol);
|
| + }
|
| +}
|
|
|
| +bool UsbAsyncApiFunction::HasDevicePermission(
|
| + scoped_refptr<usb_service::UsbDevice> device) {
|
| + UsbDevicePermission::CheckParam param(
|
| + device->vendor_id(),
|
| + device->product_id(),
|
| + UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
|
| + return extension()->permissions_data()->CheckAPIPermissionWithParam(
|
| + APIPermission::kUsbDevice, ¶m);
|
| +}
|
| +
|
| +scoped_refptr<UsbDevice> UsbAsyncApiFunction::GetDeviceOrCompleteWithError(
|
| + const Device& input_device) {
|
| UsbService* service = device::DeviceClient::Get()->GetUsbService();
|
| if (!service) {
|
| CompleteWithError(kErrorInitService);
|
| return NULL;
|
| }
|
| - scoped_refptr<UsbDevice> device;
|
| -
|
| - device = service->GetDeviceById(input_device.device);
|
|
|
| + scoped_refptr<UsbDevice> device = service->GetDeviceById(input_device.device);
|
| if (!device.get()) {
|
| CompleteWithError(kErrorNoDevice);
|
| return NULL;
|
| }
|
|
|
| - if (device->vendor_id() != input_device.vendor_id ||
|
| - device->product_id() != input_device.product_id) {
|
| + if (!HasDevicePermission(device)) {
|
| // Must act as if there is no such a device.
|
| // Otherwise can be used to finger print unauthorized devices.
|
| CompleteWithError(kErrorNoDevice);
|
| @@ -624,17 +641,20 @@ bool UsbGetDevicesFunction::Prepare() {
|
| }
|
|
|
| void UsbGetDevicesFunction::AsyncWorkStart() {
|
| - scoped_ptr<base::ListValue> result(new base::ListValue());
|
| -
|
| - 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 (!extension()->permissions_data()->CheckAPIPermissionWithParam(
|
| - APIPermission::kUsbDevice, ¶m)) {
|
| - LOG(WARNING) << "Insufficient permissions to access device.";
|
| - CompleteWithError(kErrorPermissionDenied);
|
| - return;
|
| + std::vector<UsbDeviceFilter> filters;
|
| + if (parameters_->options.filters) {
|
| + filters.resize(parameters_->options.filters->size());
|
| + for (size_t i = 0; i < parameters_->options.filters->size(); ++i) {
|
| + CreateDeviceFilter(*parameters_->options.filters->at(i).get(),
|
| + &filters[i]);
|
| + }
|
| + }
|
| + if (parameters_->options.vendor_id) {
|
| + filters.resize(filters.size() + 1);
|
| + filters.back().SetVendorId(*parameters_->options.vendor_id);
|
| + if (parameters_->options.product_id) {
|
| + filters.back().SetProductId(*parameters_->options.product_id);
|
| + }
|
| }
|
|
|
| UsbService* service = device::DeviceClient::Get()->GetUsbService();
|
| @@ -646,18 +666,15 @@ void UsbGetDevicesFunction::AsyncWorkStart() {
|
| 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;
|
| + scoped_ptr<base::ListValue> result(new base::ListValue());
|
| + for (DeviceVector::iterator it = devices.begin(); it != devices.end(); ++it) {
|
| + scoped_refptr<UsbDevice> device = *it;
|
| + if ((filters.empty() || UsbDeviceFilter::MatchesAny(device, filters)) &&
|
| + HasDevicePermission(device)) {
|
| + result->Append(PopulateDevice(it->get()));
|
| }
|
| }
|
|
|
| - for (size_t i = 0; i < devices.size(); ++i) {
|
| - result->Append(PopulateDevice(devices[i].get()));
|
| - }
|
| -
|
| SetResult(result.release());
|
| AsyncWorkCompleted();
|
| }
|
| @@ -677,7 +694,7 @@ bool UsbRequestAccessFunction::Prepare() {
|
| void UsbRequestAccessFunction::AsyncWorkStart() {
|
| #if defined(OS_CHROMEOS)
|
| scoped_refptr<UsbDevice> device =
|
| - GetDeviceOrOrCompleteWithError(parameters_->device);
|
| + GetDeviceOrCompleteWithError(parameters_->device);
|
| if (!device)
|
| return;
|
|
|
| @@ -709,7 +726,7 @@ bool UsbOpenDeviceFunction::Prepare() {
|
|
|
| void UsbOpenDeviceFunction::AsyncWorkStart() {
|
| scoped_refptr<UsbDevice> device =
|
| - GetDeviceOrOrCompleteWithError(parameters_->device);
|
| + GetDeviceOrCompleteWithError(parameters_->device);
|
| if (!device.get())
|
| return;
|
|
|
|
|