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