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" |
11 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/message_loop/message_loop_proxy.h" |
12 #include "device/core/device_client.h" | 12 #include "device/core/device_client.h" |
13 #include "device/usb/usb_device_handle.h" | 13 #include "device/usb/usb_device_handle.h" |
14 #include "device/usb/usb_service.h" | 14 #include "device/usb/usb_service.h" |
| 15 #include "extensions/browser/api/device_permissions_manager.h" |
| 16 #include "extensions/browser/api/device_permissions_prompt.h" |
| 17 #include "extensions/browser/api/extensions_api_client.h" |
15 #include "extensions/browser/api/usb/usb_device_resource.h" | 18 #include "extensions/browser/api/usb/usb_device_resource.h" |
16 #include "extensions/browser/extension_system.h" | 19 #include "extensions/browser/extension_system.h" |
17 #include "extensions/common/api/usb.h" | 20 #include "extensions/common/api/usb.h" |
18 #include "extensions/common/permissions/permissions_data.h" | 21 #include "extensions/common/permissions/permissions_data.h" |
19 #include "extensions/common/permissions/usb_device_permission.h" | 22 #include "extensions/common/permissions/usb_device_permission.h" |
20 | 23 |
21 namespace usb = extensions::core_api::usb; | 24 namespace usb = extensions::core_api::usb; |
22 namespace BulkTransfer = usb::BulkTransfer; | 25 namespace BulkTransfer = usb::BulkTransfer; |
23 namespace ClaimInterface = usb::ClaimInterface; | 26 namespace ClaimInterface = usb::ClaimInterface; |
24 namespace CloseDevice = usb::CloseDevice; | 27 namespace CloseDevice = usb::CloseDevice; |
25 namespace ControlTransfer = usb::ControlTransfer; | 28 namespace ControlTransfer = usb::ControlTransfer; |
26 namespace FindDevices = usb::FindDevices; | 29 namespace FindDevices = usb::FindDevices; |
27 namespace GetDevices = usb::GetDevices; | 30 namespace GetDevices = usb::GetDevices; |
| 31 namespace GetUserSelectedDevices = usb::GetUserSelectedDevices; |
28 namespace InterruptTransfer = usb::InterruptTransfer; | 32 namespace InterruptTransfer = usb::InterruptTransfer; |
29 namespace IsochronousTransfer = usb::IsochronousTransfer; | 33 namespace IsochronousTransfer = usb::IsochronousTransfer; |
30 namespace GetConfiguration = usb::GetConfiguration; | 34 namespace GetConfiguration = usb::GetConfiguration; |
31 namespace ListInterfaces = usb::ListInterfaces; | 35 namespace ListInterfaces = usb::ListInterfaces; |
32 namespace OpenDevice = usb::OpenDevice; | 36 namespace OpenDevice = usb::OpenDevice; |
33 namespace ReleaseInterface = usb::ReleaseInterface; | 37 namespace ReleaseInterface = usb::ReleaseInterface; |
34 namespace RequestAccess = usb::RequestAccess; | 38 namespace RequestAccess = usb::RequestAccess; |
35 namespace ResetDevice = usb::ResetDevice; | 39 namespace ResetDevice = usb::ResetDevice; |
36 namespace SetInterfaceAlternateSetting = usb::SetInterfaceAlternateSetting; | 40 namespace SetInterfaceAlternateSetting = usb::SetInterfaceAlternateSetting; |
37 | 41 |
38 using content::BrowserThread; | 42 using content::BrowserThread; |
| 43 using device::UsbConfigDescriptor; |
| 44 using device::UsbDevice; |
| 45 using device::UsbDeviceFilter; |
| 46 using device::UsbDeviceHandle; |
| 47 using device::UsbEndpointDescriptor; |
| 48 using device::UsbEndpointDirection; |
| 49 using device::UsbInterfaceDescriptor; |
| 50 using device::UsbService; |
| 51 using device::UsbSynchronizationType; |
| 52 using device::UsbTransferStatus; |
| 53 using device::UsbTransferType; |
| 54 using device::UsbUsageType; |
| 55 using std::string; |
| 56 using std::vector; |
39 using usb::ConfigDescriptor; | 57 using usb::ConfigDescriptor; |
40 using usb::ControlTransferInfo; | 58 using usb::ControlTransferInfo; |
41 using usb::ConnectionHandle; | 59 using usb::ConnectionHandle; |
42 using usb::Device; | 60 using usb::Device; |
43 using usb::Direction; | 61 using usb::Direction; |
44 using usb::EndpointDescriptor; | 62 using usb::EndpointDescriptor; |
45 using usb::GenericTransferInfo; | 63 using usb::GenericTransferInfo; |
46 using usb::InterfaceDescriptor; | 64 using usb::InterfaceDescriptor; |
47 using usb::IsochronousTransferInfo; | 65 using usb::IsochronousTransferInfo; |
48 using usb::Recipient; | 66 using usb::Recipient; |
49 using usb::RequestType; | 67 using usb::RequestType; |
50 using usb::SynchronizationType; | 68 using usb::SynchronizationType; |
51 using usb::TransferType; | 69 using usb::TransferType; |
52 using usb::UsageType; | 70 using usb::UsageType; |
53 using device::UsbConfigDescriptor; | |
54 using device::UsbDevice; | |
55 using device::UsbDeviceFilter; | |
56 using device::UsbDeviceHandle; | |
57 using device::UsbEndpointDescriptor; | |
58 using device::UsbEndpointDirection; | |
59 using device::UsbInterfaceDescriptor; | |
60 using device::UsbService; | |
61 using device::UsbSynchronizationType; | |
62 using device::UsbTransferStatus; | |
63 using device::UsbTransferType; | |
64 using device::UsbUsageType; | |
65 | 71 |
66 typedef std::vector<scoped_refptr<UsbDevice> > DeviceVector; | 72 typedef std::vector<scoped_refptr<UsbDevice> > DeviceVector; |
67 typedef scoped_ptr<DeviceVector> ScopedDeviceVector; | 73 typedef scoped_ptr<DeviceVector> ScopedDeviceVector; |
68 | 74 |
69 namespace { | 75 namespace { |
70 | 76 |
71 const char kDataKey[] = "data"; | 77 const char kDataKey[] = "data"; |
72 const char kResultCodeKey[] = "resultCode"; | 78 const char kResultCodeKey[] = "resultCode"; |
73 | 79 |
74 const char kErrorInitService[] = "Failed to initialize USB service."; | 80 const char kErrorInitService[] = "Failed to initialize USB service."; |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 base::Value* PopulateConnectionHandle(int handle, | 293 base::Value* PopulateConnectionHandle(int handle, |
288 int vendor_id, | 294 int vendor_id, |
289 int product_id) { | 295 int product_id) { |
290 ConnectionHandle result; | 296 ConnectionHandle result; |
291 result.handle = handle; | 297 result.handle = handle; |
292 result.vendor_id = vendor_id; | 298 result.vendor_id = vendor_id; |
293 result.product_id = product_id; | 299 result.product_id = product_id; |
294 return result.ToValue().release(); | 300 return result.ToValue().release(); |
295 } | 301 } |
296 | 302 |
297 base::Value* PopulateDevice(UsbDevice* device) { | 303 base::Value* PopulateDevice(const UsbDevice* device) { |
298 Device result; | 304 Device result; |
299 result.device = device->unique_id(); | 305 result.device = device->unique_id(); |
300 result.vendor_id = device->vendor_id(); | 306 result.vendor_id = device->vendor_id(); |
301 result.product_id = device->product_id(); | 307 result.product_id = device->product_id(); |
302 return result.ToValue().release(); | 308 return result.ToValue().release(); |
303 } | 309 } |
304 | 310 |
305 TransferType ConvertTransferTypeToApi(const UsbTransferType& input) { | 311 TransferType ConvertTransferTypeToApi(const UsbTransferType& input) { |
306 switch (input) { | 312 switch (input) { |
307 case device::USB_TRANSFER_CONTROL: | 313 case device::USB_TRANSFER_CONTROL: |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 ConvertInterfaceDescriptor(*interfaceIt, interface.get()); | 418 ConvertInterfaceDescriptor(*interfaceIt, interface.get()); |
413 output->interfaces.push_back(interface); | 419 output->interfaces.push_back(interface); |
414 } | 420 } |
415 if (input.extra_data.size() > 0) { | 421 if (input.extra_data.size() > 0) { |
416 output->extra_data = | 422 output->extra_data = |
417 std::string(reinterpret_cast<const char*>(&input.extra_data[0]), | 423 std::string(reinterpret_cast<const char*>(&input.extra_data[0]), |
418 input.extra_data.size()); | 424 input.extra_data.size()); |
419 } | 425 } |
420 } | 426 } |
421 | 427 |
| 428 void ConvertDeviceFilter(const usb::DeviceFilter& input, |
| 429 UsbDeviceFilter* output) { |
| 430 if (input.vendor_id) { |
| 431 output->SetVendorId(*input.vendor_id); |
| 432 } |
| 433 if (input.product_id) { |
| 434 output->SetProductId(*input.product_id); |
| 435 } |
| 436 if (input.interface_class) { |
| 437 output->SetInterfaceClass(*input.interface_class); |
| 438 } |
| 439 if (input.interface_subclass) { |
| 440 output->SetInterfaceSubclass(*input.interface_subclass); |
| 441 } |
| 442 if (input.interface_protocol) { |
| 443 output->SetInterfaceProtocol(*input.interface_protocol); |
| 444 } |
| 445 } |
| 446 |
422 } // namespace | 447 } // namespace |
423 | 448 |
424 namespace extensions { | 449 namespace extensions { |
425 | 450 |
426 UsbAsyncApiFunction::UsbAsyncApiFunction() : manager_(NULL) { | 451 UsbAsyncApiFunction::UsbAsyncApiFunction() : manager_(NULL) { |
427 } | 452 } |
428 | 453 |
429 UsbAsyncApiFunction::~UsbAsyncApiFunction() { | 454 UsbAsyncApiFunction::~UsbAsyncApiFunction() { |
430 } | 455 } |
431 | 456 |
432 bool UsbAsyncApiFunction::PrePrepare() { | 457 bool UsbAsyncApiFunction::PrePrepare() { |
433 manager_ = ApiResourceManager<UsbDeviceResource>::Get(browser_context()); | 458 manager_ = ApiResourceManager<UsbDeviceResource>::Get(browser_context()); |
434 set_work_thread_id(BrowserThread::FILE); | 459 set_work_thread_id(BrowserThread::FILE); |
435 return manager_ != NULL; | 460 return manager_ != NULL; |
436 } | 461 } |
437 | 462 |
438 bool UsbAsyncApiFunction::Respond() { | 463 bool UsbAsyncApiFunction::Respond() { |
439 return error_.empty(); | 464 return error_.empty(); |
440 } | 465 } |
441 | 466 |
442 // static | |
443 void UsbAsyncApiFunction::CreateDeviceFilter(const usb::DeviceFilter& input, | |
444 UsbDeviceFilter* output) { | |
445 if (input.vendor_id) { | |
446 output->SetVendorId(*input.vendor_id); | |
447 } | |
448 if (input.product_id) { | |
449 output->SetProductId(*input.product_id); | |
450 } | |
451 if (input.interface_class) { | |
452 output->SetInterfaceClass(*input.interface_class); | |
453 } | |
454 if (input.interface_subclass) { | |
455 output->SetInterfaceSubclass(*input.interface_subclass); | |
456 } | |
457 if (input.interface_protocol) { | |
458 output->SetInterfaceProtocol(*input.interface_protocol); | |
459 } | |
460 } | |
461 | |
462 bool UsbAsyncApiFunction::HasDevicePermission(scoped_refptr<UsbDevice> device) { | 467 bool UsbAsyncApiFunction::HasDevicePermission(scoped_refptr<UsbDevice> device) { |
463 UsbDevicePermission::CheckParam param( | 468 UsbDevicePermission::CheckParam param( |
464 device->vendor_id(), | 469 device->vendor_id(), |
465 device->product_id(), | 470 device->product_id(), |
466 UsbDevicePermissionData::UNSPECIFIED_INTERFACE); | 471 UsbDevicePermissionData::UNSPECIFIED_INTERFACE); |
467 return extension()->permissions_data()->CheckAPIPermissionWithParam( | 472 if (extension()->permissions_data()->CheckAPIPermissionWithParam( |
468 APIPermission::kUsbDevice, ¶m); | 473 APIPermission::kUsbDevice, ¶m)) { |
| 474 return true; |
| 475 } |
| 476 |
| 477 if (device_permissions_.get()) { |
| 478 return device_permissions_->CheckUsbDevice(device); |
| 479 } |
| 480 |
| 481 return false; |
469 } | 482 } |
470 | 483 |
471 scoped_refptr<UsbDevice> UsbAsyncApiFunction::GetDeviceOrCompleteWithError( | 484 scoped_refptr<UsbDevice> UsbAsyncApiFunction::GetDeviceOrCompleteWithError( |
472 const Device& input_device) { | 485 const Device& input_device) { |
473 UsbService* service = device::DeviceClient::Get()->GetUsbService(); | 486 UsbService* service = device::DeviceClient::Get()->GetUsbService(); |
474 if (!service) { | 487 if (!service) { |
475 CompleteWithError(kErrorInitService); | 488 CompleteWithError(kErrorInitService); |
476 return NULL; | 489 return NULL; |
477 } | 490 } |
478 | 491 |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 | 663 |
651 UsbGetDevicesFunction::UsbGetDevicesFunction() { | 664 UsbGetDevicesFunction::UsbGetDevicesFunction() { |
652 } | 665 } |
653 | 666 |
654 UsbGetDevicesFunction::~UsbGetDevicesFunction() { | 667 UsbGetDevicesFunction::~UsbGetDevicesFunction() { |
655 } | 668 } |
656 | 669 |
657 bool UsbGetDevicesFunction::Prepare() { | 670 bool UsbGetDevicesFunction::Prepare() { |
658 parameters_ = GetDevices::Params::Create(*args_); | 671 parameters_ = GetDevices::Params::Create(*args_); |
659 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 672 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 673 device_permissions_ = DevicePermissionsManager::Get(browser_context()) |
| 674 ->GetForExtension(extension()->id()); |
660 return true; | 675 return true; |
661 } | 676 } |
662 | 677 |
663 void UsbGetDevicesFunction::AsyncWorkStart() { | 678 void UsbGetDevicesFunction::AsyncWorkStart() { |
664 std::vector<UsbDeviceFilter> filters; | 679 std::vector<UsbDeviceFilter> filters; |
665 if (parameters_->options.filters) { | 680 if (parameters_->options.filters) { |
666 filters.resize(parameters_->options.filters->size()); | 681 filters.resize(parameters_->options.filters->size()); |
667 for (size_t i = 0; i < parameters_->options.filters->size(); ++i) { | 682 for (size_t i = 0; i < parameters_->options.filters->size(); ++i) { |
668 CreateDeviceFilter(*parameters_->options.filters->at(i).get(), | 683 ConvertDeviceFilter(*parameters_->options.filters->at(i).get(), |
669 &filters[i]); | 684 &filters[i]); |
670 } | 685 } |
671 } | 686 } |
672 if (parameters_->options.vendor_id) { | 687 if (parameters_->options.vendor_id) { |
673 filters.resize(filters.size() + 1); | 688 filters.resize(filters.size() + 1); |
674 filters.back().SetVendorId(*parameters_->options.vendor_id); | 689 filters.back().SetVendorId(*parameters_->options.vendor_id); |
675 if (parameters_->options.product_id) { | 690 if (parameters_->options.product_id) { |
676 filters.back().SetProductId(*parameters_->options.product_id); | 691 filters.back().SetProductId(*parameters_->options.product_id); |
677 } | 692 } |
678 } | 693 } |
679 | 694 |
(...skipping 12 matching lines...) Expand all Loading... |
692 if ((filters.empty() || UsbDeviceFilter::MatchesAny(device, filters)) && | 707 if ((filters.empty() || UsbDeviceFilter::MatchesAny(device, filters)) && |
693 HasDevicePermission(device)) { | 708 HasDevicePermission(device)) { |
694 result->Append(PopulateDevice(it->get())); | 709 result->Append(PopulateDevice(it->get())); |
695 } | 710 } |
696 } | 711 } |
697 | 712 |
698 SetResult(result.release()); | 713 SetResult(result.release()); |
699 AsyncWorkCompleted(); | 714 AsyncWorkCompleted(); |
700 } | 715 } |
701 | 716 |
| 717 UsbGetUserSelectedDevicesFunction::UsbGetUserSelectedDevicesFunction() { |
| 718 } |
| 719 |
| 720 UsbGetUserSelectedDevicesFunction::~UsbGetUserSelectedDevicesFunction() { |
| 721 } |
| 722 |
| 723 AsyncApiFunction::ResponseAction UsbGetUserSelectedDevicesFunction::Run() { |
| 724 scoped_ptr<extensions::core_api::usb::GetUserSelectedDevices::Params> |
| 725 parameters = GetUserSelectedDevices::Params::Create(*args_); |
| 726 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
| 727 |
| 728 if (!user_gesture()) { |
| 729 return RespondNow(OneArgument(new base::ListValue())); |
| 730 } |
| 731 |
| 732 bool multiple = false; |
| 733 if (parameters->options.multiple) { |
| 734 multiple = *parameters->options.multiple; |
| 735 } |
| 736 |
| 737 std::vector<UsbDeviceFilter> filters; |
| 738 if (parameters->options.filters) { |
| 739 filters.resize(parameters->options.filters->size()); |
| 740 for (size_t i = 0; i < parameters->options.filters->size(); ++i) { |
| 741 ConvertDeviceFilter(*parameters->options.filters->at(i).get(), |
| 742 &filters[i]); |
| 743 } |
| 744 } |
| 745 |
| 746 prompt_.reset(new DevicePermissionsPrompt(GetAssociatedWebContents())); |
| 747 AddRef(); |
| 748 prompt_->AskForUsbDevices( |
| 749 this, extension(), browser_context(), multiple, filters); |
| 750 return RespondLater(); |
| 751 } |
| 752 |
| 753 void UsbGetUserSelectedDevicesFunction::UsbDevicesChosen( |
| 754 const std::vector<scoped_refptr<UsbDevice>>& devices) { |
| 755 scoped_ptr<base::ListValue> result(new base::ListValue()); |
| 756 for (const auto& device : devices) { |
| 757 result->Append(PopulateDevice(device.get())); |
| 758 } |
| 759 |
| 760 SetResult(result.release()); |
| 761 SendResponse(true); |
| 762 Release(); |
| 763 } |
| 764 |
702 UsbRequestAccessFunction::UsbRequestAccessFunction() { | 765 UsbRequestAccessFunction::UsbRequestAccessFunction() { |
703 } | 766 } |
704 | 767 |
705 UsbRequestAccessFunction::~UsbRequestAccessFunction() { | 768 UsbRequestAccessFunction::~UsbRequestAccessFunction() { |
706 } | 769 } |
707 | 770 |
708 bool UsbRequestAccessFunction::Prepare() { | 771 bool UsbRequestAccessFunction::Prepare() { |
709 parameters_ = RequestAccess::Params::Create(*args_); | 772 parameters_ = RequestAccess::Params::Create(*args_); |
710 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 773 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 774 device_permissions_ = DevicePermissionsManager::Get(browser_context()) |
| 775 ->GetForExtension(extension()->id()); |
711 return true; | 776 return true; |
712 } | 777 } |
713 | 778 |
714 void UsbRequestAccessFunction::AsyncWorkStart() { | 779 void UsbRequestAccessFunction::AsyncWorkStart() { |
715 #if defined(OS_CHROMEOS) | 780 #if defined(OS_CHROMEOS) |
716 scoped_refptr<UsbDevice> device = | 781 scoped_refptr<UsbDevice> device = |
717 GetDeviceOrCompleteWithError(parameters_->device); | 782 GetDeviceOrCompleteWithError(parameters_->device); |
718 if (!device.get()) | 783 if (!device.get()) |
719 return; | 784 return; |
720 | 785 |
(...skipping 13 matching lines...) Expand all Loading... |
734 | 799 |
735 UsbOpenDeviceFunction::UsbOpenDeviceFunction() { | 800 UsbOpenDeviceFunction::UsbOpenDeviceFunction() { |
736 } | 801 } |
737 | 802 |
738 UsbOpenDeviceFunction::~UsbOpenDeviceFunction() { | 803 UsbOpenDeviceFunction::~UsbOpenDeviceFunction() { |
739 } | 804 } |
740 | 805 |
741 bool UsbOpenDeviceFunction::Prepare() { | 806 bool UsbOpenDeviceFunction::Prepare() { |
742 parameters_ = OpenDevice::Params::Create(*args_); | 807 parameters_ = OpenDevice::Params::Create(*args_); |
743 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 808 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
| 809 device_permissions_ = DevicePermissionsManager::Get(browser_context()) |
| 810 ->GetForExtension(extension()->id()); |
744 return true; | 811 return true; |
745 } | 812 } |
746 | 813 |
747 void UsbOpenDeviceFunction::AsyncWorkStart() { | 814 void UsbOpenDeviceFunction::AsyncWorkStart() { |
748 scoped_refptr<UsbDevice> device = | 815 scoped_refptr<UsbDevice> device = |
749 GetDeviceOrCompleteWithError(parameters_->device); | 816 GetDeviceOrCompleteWithError(parameters_->device); |
750 if (!device.get()) | 817 if (!device.get()) |
751 return; | 818 return; |
752 | 819 |
753 handle_ = device->Open(); | 820 handle_ = device->Open(); |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1170 SetResult(new base::FundamentalValue(false)); | 1237 SetResult(new base::FundamentalValue(false)); |
1171 CompleteWithError(kErrorResetDevice); | 1238 CompleteWithError(kErrorResetDevice); |
1172 return; | 1239 return; |
1173 } | 1240 } |
1174 | 1241 |
1175 SetResult(new base::FundamentalValue(true)); | 1242 SetResult(new base::FundamentalValue(true)); |
1176 AsyncWorkCompleted(); | 1243 AsyncWorkCompleted(); |
1177 } | 1244 } |
1178 | 1245 |
1179 } // namespace extensions | 1246 } // namespace extensions |
OLD | NEW |