OLD | NEW |
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 Loading... |
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 Loading... |
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, ¶m); |
| 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, ¶m)) { | |
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 Loading... |
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, ¶m)) { | 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 Loading... |
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 Loading... |
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 |
OLD | NEW |