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

Side by Side Diff: extensions/browser/api/usb/usb_api.cc

Issue 517923002: Add more generic filters to the chrome.usb.getDevices API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Clean up the USB API documentation. Created 6 years, 3 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/browser/api/usb/usb_api.h" 5 #include "extensions/browser/api/usb/usb_api.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 using usb::GenericTransferInfo; 44 using usb::GenericTransferInfo;
45 using usb::InterfaceDescriptor; 45 using usb::InterfaceDescriptor;
46 using usb::IsochronousTransferInfo; 46 using usb::IsochronousTransferInfo;
47 using usb::Recipient; 47 using usb::Recipient;
48 using usb::RequestType; 48 using usb::RequestType;
49 using usb::SynchronizationType; 49 using usb::SynchronizationType;
50 using usb::TransferType; 50 using usb::TransferType;
51 using usb::UsageType; 51 using usb::UsageType;
52 using usb_service::UsbConfigDescriptor; 52 using usb_service::UsbConfigDescriptor;
53 using usb_service::UsbDevice; 53 using usb_service::UsbDevice;
54 using usb_service::UsbDeviceFilter;
54 using usb_service::UsbDeviceHandle; 55 using usb_service::UsbDeviceHandle;
55 using usb_service::UsbEndpointDescriptor; 56 using usb_service::UsbEndpointDescriptor;
56 using usb_service::UsbEndpointDirection; 57 using usb_service::UsbEndpointDirection;
57 using usb_service::UsbInterfaceAltSettingDescriptor; 58 using usb_service::UsbInterfaceAltSettingDescriptor;
58 using usb_service::UsbInterfaceDescriptor; 59 using usb_service::UsbInterfaceDescriptor;
59 using usb_service::UsbService; 60 using usb_service::UsbService;
60 using usb_service::UsbSynchronizationType; 61 using usb_service::UsbSynchronizationType;
61 using usb_service::UsbTransferStatus; 62 using usb_service::UsbTransferStatus;
62 using usb_service::UsbTransferType; 63 using usb_service::UsbTransferType;
63 using usb_service::UsbUsageType; 64 using usb_service::UsbUsageType;
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 bool UsbAsyncApiFunction::PrePrepare() { 410 bool UsbAsyncApiFunction::PrePrepare() {
410 manager_ = ApiResourceManager<UsbDeviceResource>::Get(browser_context()); 411 manager_ = ApiResourceManager<UsbDeviceResource>::Get(browser_context());
411 set_work_thread_id(BrowserThread::FILE); 412 set_work_thread_id(BrowserThread::FILE);
412 return manager_ != NULL; 413 return manager_ != NULL;
413 } 414 }
414 415
415 bool UsbAsyncApiFunction::Respond() { 416 bool UsbAsyncApiFunction::Respond() {
416 return error_.empty(); 417 return error_.empty();
417 } 418 }
418 419
419 scoped_refptr<UsbDevice> UsbAsyncApiFunction::GetDeviceOrOrCompleteWithError( 420 // static
421 void UsbAsyncApiFunction::CreateDeviceFilter(const usb::DeviceFilter& input,
422 UsbDeviceFilter* output) {
423 if (input.vendor_id) {
424 output->SetVendorId(*input.vendor_id);
425 }
426 if (input.product_id) {
427 output->SetProductId(*input.product_id);
428 }
429 if (input.interface_class) {
430 output->SetInterfaceClass(*input.interface_class);
431 }
432 if (input.interface_subclass) {
433 output->SetInterfaceSubclass(*input.interface_subclass);
434 }
435 if (input.interface_protocol) {
436 output->SetInterfaceProtocol(*input.interface_protocol);
437 }
438 }
439
440 bool UsbAsyncApiFunction::HasDevicePermission(
441 scoped_refptr<usb_service::UsbDevice> device) {
442 UsbDevicePermission::CheckParam param(
443 device->vendor_id(),
444 device->product_id(),
445 UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
446 return extension()->permissions_data()->CheckAPIPermissionWithParam(
447 APIPermission::kUsbDevice, &param);
448 }
449
450 scoped_refptr<UsbDevice> UsbAsyncApiFunction::GetDeviceOrCompleteWithError(
420 const Device& input_device) { 451 const Device& input_device) {
421 const uint16_t vendor_id = input_device.vendor_id;
422 const uint16_t product_id = input_device.product_id;
423 UsbDevicePermission::CheckParam param(
424 vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
425 if (!extension()->permissions_data()->CheckAPIPermissionWithParam(
426 APIPermission::kUsbDevice, &param)) {
427 LOG(WARNING) << "Insufficient permissions to access device.";
428 CompleteWithError(kErrorPermissionDenied);
429 return NULL;
430 }
431
432 UsbService* service = UsbService::GetInstance(); 452 UsbService* service = UsbService::GetInstance();
433 if (!service) { 453 if (!service) {
434 CompleteWithError(kErrorInitService); 454 CompleteWithError(kErrorInitService);
435 return NULL; 455 return NULL;
436 } 456 }
437 scoped_refptr<UsbDevice> device;
438 457
439 device = service->GetDeviceById(input_device.device); 458 scoped_refptr<UsbDevice> device = service->GetDeviceById(input_device.device);
440
441 if (!device.get()) { 459 if (!device.get()) {
442 CompleteWithError(kErrorNoDevice); 460 CompleteWithError(kErrorNoDevice);
443 return NULL; 461 return NULL;
444 } 462 }
445 463
446 if (device->vendor_id() != input_device.vendor_id || 464 if (!HasDevicePermission(device)) {
447 device->product_id() != input_device.product_id) {
448 // Must act as if there is no such a device. 465 // Must act as if there is no such a device.
449 // Otherwise can be used to finger print unauthorized devices. 466 // Otherwise can be used to finger print unauthorized devices.
450 CompleteWithError(kErrorNoDevice); 467 CompleteWithError(kErrorNoDevice);
451 return NULL; 468 return NULL;
452 } 469 }
453 470
454 return device; 471 return device;
455 } 472 }
456 473
457 scoped_refptr<UsbDeviceHandle> 474 scoped_refptr<UsbDeviceHandle>
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 UsbGetDevicesFunction::~UsbGetDevicesFunction() { 633 UsbGetDevicesFunction::~UsbGetDevicesFunction() {
617 } 634 }
618 635
619 bool UsbGetDevicesFunction::Prepare() { 636 bool UsbGetDevicesFunction::Prepare() {
620 parameters_ = GetDevices::Params::Create(*args_); 637 parameters_ = GetDevices::Params::Create(*args_);
621 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 638 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
622 return true; 639 return true;
623 } 640 }
624 641
625 void UsbGetDevicesFunction::AsyncWorkStart() { 642 void UsbGetDevicesFunction::AsyncWorkStart() {
626 scoped_ptr<base::ListValue> result(new base::ListValue()); 643 std::vector<UsbDeviceFilter> filters;
627 644 if (parameters_->options.filters) {
628 const uint16_t vendor_id = parameters_->options.vendor_id; 645 filters.resize(parameters_->options.filters->size());
629 const uint16_t product_id = parameters_->options.product_id; 646 for (size_t i = 0; i < parameters_->options.filters->size(); ++i) {
630 UsbDevicePermission::CheckParam param( 647 CreateDeviceFilter(*parameters_->options.filters->at(i).get(),
631 vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE); 648 &filters[i]);
632 if (!extension()->permissions_data()->CheckAPIPermissionWithParam( 649 }
633 APIPermission::kUsbDevice, &param)) { 650 }
634 LOG(WARNING) << "Insufficient permissions to access device."; 651 if (parameters_->options.vendor_id) {
635 CompleteWithError(kErrorPermissionDenied); 652 filters.resize(filters.size() + 1);
636 return; 653 filters.back().SetVendorId(*parameters_->options.vendor_id);
654 if (parameters_->options.product_id) {
655 filters.back().SetProductId(*parameters_->options.product_id);
656 }
637 } 657 }
638 658
639 UsbService* service = UsbService::GetInstance(); 659 UsbService* service = UsbService::GetInstance();
640 if (!service) { 660 if (!service) {
641 CompleteWithError(kErrorInitService); 661 CompleteWithError(kErrorInitService);
642 return; 662 return;
643 } 663 }
644 664
645 DeviceVector devices; 665 DeviceVector devices;
646 service->GetDevices(&devices); 666 service->GetDevices(&devices);
647 667
648 for (DeviceVector::iterator it = devices.begin(); it != devices.end();) { 668 scoped_ptr<base::ListValue> result(new base::ListValue());
649 if ((*it)->vendor_id() != vendor_id || (*it)->product_id() != product_id) { 669 for (DeviceVector::iterator it = devices.begin(); it != devices.end(); ++it) {
650 it = devices.erase(it); 670 scoped_refptr<UsbDevice> device = *it;
651 } else { 671 if ((filters.empty() || UsbDeviceFilter::MatchesAny(device, filters)) &&
652 ++it; 672 HasDevicePermission(device)) {
673 result->Append(PopulateDevice(it->get()));
653 } 674 }
654 } 675 }
655 676
656 for (size_t i = 0; i < devices.size(); ++i) {
657 result->Append(PopulateDevice(devices[i].get()));
658 }
659
660 SetResult(result.release()); 677 SetResult(result.release());
661 AsyncWorkCompleted(); 678 AsyncWorkCompleted();
662 } 679 }
663 680
664 UsbRequestAccessFunction::UsbRequestAccessFunction() { 681 UsbRequestAccessFunction::UsbRequestAccessFunction() {
665 } 682 }
666 683
667 UsbRequestAccessFunction::~UsbRequestAccessFunction() { 684 UsbRequestAccessFunction::~UsbRequestAccessFunction() {
668 } 685 }
669 686
670 bool UsbRequestAccessFunction::Prepare() { 687 bool UsbRequestAccessFunction::Prepare() {
671 parameters_ = RequestAccess::Params::Create(*args_); 688 parameters_ = RequestAccess::Params::Create(*args_);
672 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 689 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
673 return true; 690 return true;
674 } 691 }
675 692
676 void UsbRequestAccessFunction::AsyncWorkStart() { 693 void UsbRequestAccessFunction::AsyncWorkStart() {
677 #if defined(OS_CHROMEOS) 694 #if defined(OS_CHROMEOS)
678 scoped_refptr<UsbDevice> device = 695 scoped_refptr<UsbDevice> device =
679 GetDeviceOrOrCompleteWithError(parameters_->device); 696 GetDeviceOrCompleteWithError(parameters_->device);
680 if (!device) 697 if (!device)
681 return; 698 return;
682 699
683 device->RequestUsbAccess( 700 device->RequestUsbAccess(
684 parameters_->interface_id, 701 parameters_->interface_id,
685 base::Bind(&UsbRequestAccessFunction::OnCompleted, this)); 702 base::Bind(&UsbRequestAccessFunction::OnCompleted, this));
686 #else 703 #else
687 SetResult(new base::FundamentalValue(false)); 704 SetResult(new base::FundamentalValue(false));
688 CompleteWithError(kErrorNotSupported); 705 CompleteWithError(kErrorNotSupported);
689 #endif // OS_CHROMEOS 706 #endif // OS_CHROMEOS
(...skipping 11 matching lines...) Expand all
701 } 718 }
702 719
703 bool UsbOpenDeviceFunction::Prepare() { 720 bool UsbOpenDeviceFunction::Prepare() {
704 parameters_ = OpenDevice::Params::Create(*args_); 721 parameters_ = OpenDevice::Params::Create(*args_);
705 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 722 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
706 return true; 723 return true;
707 } 724 }
708 725
709 void UsbOpenDeviceFunction::AsyncWorkStart() { 726 void UsbOpenDeviceFunction::AsyncWorkStart() {
710 scoped_refptr<UsbDevice> device = 727 scoped_refptr<UsbDevice> device =
711 GetDeviceOrOrCompleteWithError(parameters_->device); 728 GetDeviceOrCompleteWithError(parameters_->device);
712 if (!device.get()) 729 if (!device.get())
713 return; 730 return;
714 731
715 handle_ = device->Open(); 732 handle_ = device->Open();
716 if (!handle_.get()) { 733 if (!handle_.get()) {
717 SetError(kErrorOpen); 734 SetError(kErrorOpen);
718 AsyncWorkCompleted(); 735 AsyncWorkCompleted();
719 return; 736 return;
720 } 737 }
721 738
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
1199 SetResult(new base::FundamentalValue(false)); 1216 SetResult(new base::FundamentalValue(false));
1200 CompleteWithError(kErrorResetDevice); 1217 CompleteWithError(kErrorResetDevice);
1201 return; 1218 return;
1202 } 1219 }
1203 1220
1204 SetResult(new base::FundamentalValue(true)); 1221 SetResult(new base::FundamentalValue(true));
1205 AsyncWorkCompleted(); 1222 AsyncWorkCompleted();
1206 } 1223 }
1207 1224
1208 } // namespace extensions 1225 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698