diff options
-rw-r--r-- | chrome/browser/extensions/api/usb/usb_api.cc | 9 | ||||
-rw-r--r-- | chrome/browser/usb/usb_service.cc | 2 | ||||
-rw-r--r-- | chrome/browser/usb/usb_service.h | 1 | ||||
-rw-r--r-- | chrome/common/extensions/api/usb.idl | 1 | ||||
-rw-r--r-- | chrome/common/extensions/permissions/usb_device_permission.h | 7 | ||||
-rw-r--r-- | chrome/common/extensions/permissions/usb_device_permission_data.cc | 29 | ||||
-rw-r--r-- | chrome/common/extensions/permissions/usb_device_permission_data.h | 12 | ||||
-rw-r--r-- | chrome/common/extensions/permissions/usb_device_permission_unittest.cc | 16 | ||||
-rw-r--r-- | chromeos/dbus/permission_broker_client.cc | 6 | ||||
-rw-r--r-- | chromeos/dbus/permission_broker_client.h | 17 |
10 files changed, 77 insertions, 23 deletions
diff --git a/chrome/browser/extensions/api/usb/usb_api.cc b/chrome/browser/extensions/api/usb/usb_api.cc index 453f8940..948dece 100644 --- a/chrome/browser/extensions/api/usb/usb_api.cc +++ b/chrome/browser/extensions/api/usb/usb_api.cc @@ -428,7 +428,10 @@ void UsbFindDevicesFunction::AsyncWorkStart() { 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); + int interface_id = parameters_->options.interface_id.get() ? + *parameters_->options.interface_id.get() : + UsbDevicePermissionData::ANY_INTERFACE; + UsbDevicePermission::CheckParam param(vendor_id, product_id, interface_id); if (!PermissionsData::CheckAPIPermissionWithParam( GetExtension(), APIPermission::kUsbDevice, ¶m)) { LOG(WARNING) << "Insufficient permissions to access device."; @@ -444,8 +447,8 @@ void UsbFindDevicesFunction::AsyncWorkStart() { return; } - service->FindDevices(vendor_id, product_id, &devices_, base::Bind( - &UsbFindDevicesFunction::OnCompleted, this)); + service->FindDevices(vendor_id, product_id, interface_id, &devices_, + base::Bind(&UsbFindDevicesFunction::OnCompleted, this)); } void UsbFindDevicesFunction::OnCompleted() { diff --git a/chrome/browser/usb/usb_service.cc b/chrome/browser/usb/usb_service.cc index bc8fe41..038786d 100644 --- a/chrome/browser/usb/usb_service.cc +++ b/chrome/browser/usb/usb_service.cc @@ -71,6 +71,7 @@ void UsbService::Cleanup() { void UsbService::FindDevices(const uint16 vendor_id, const uint16 product_id, + int interface_id, vector<scoped_refptr<UsbDevice> >* devices, const base::Callback<void()>& callback) { DCHECK(event_handler_) << "FindDevices called after event handler stopped."; @@ -88,6 +89,7 @@ void UsbService::FindDevices(const uint16 vendor_id, client->RequestUsbAccess(vendor_id, product_id, + interface_id, base::Bind(&UsbService::FindDevicesImpl, base::Unretained(this), vendor_id, diff --git a/chrome/browser/usb/usb_service.h b/chrome/browser/usb/usb_service.h index 3e9d34e..8e04ce2 100644 --- a/chrome/browser/usb/usb_service.h +++ b/chrome/browser/usb/usb_service.h @@ -36,6 +36,7 @@ class UsbService : public BrowserContextKeyedService { // |devices| before use. Calls |callback| once |devices| is populated. void FindDevices(const uint16 vendor_id, const uint16 product_id, + int interface_id, std::vector<scoped_refptr<UsbDevice> >* devices, const base::Callback<void()>& callback); diff --git a/chrome/common/extensions/api/usb.idl b/chrome/common/extensions/api/usb.idl index 89a0e60..068f34b 100644 --- a/chrome/common/extensions/api/usb.idl +++ b/chrome/common/extensions/api/usb.idl @@ -123,6 +123,7 @@ namespace usb { dictionary FindDevicesOptions { long vendorId; long productId; + long? interfaceId; }; callback VoidCallback = void (); diff --git a/chrome/common/extensions/permissions/usb_device_permission.h b/chrome/common/extensions/permissions/usb_device_permission.h index 77ea15d..211b8ef 100644 --- a/chrome/common/extensions/permissions/usb_device_permission.h +++ b/chrome/common/extensions/permissions/usb_device_permission.h @@ -17,10 +17,13 @@ class UsbDevicePermission UsbDevicePermission> { public: struct CheckParam : public APIPermission::CheckParam { - CheckParam(uint16 vendor_id, uint16 product_id) - : vendor_id(vendor_id), product_id(product_id) {} + CheckParam(uint16 vendor_id, uint16 product_id, int interface_id) + : vendor_id(vendor_id), + product_id(product_id), + interface_id(interface_id) {} const uint16 vendor_id; const uint16 product_id; + const int interface_id; }; explicit UsbDevicePermission(const APIPermissionInfo* info); diff --git a/chrome/common/extensions/permissions/usb_device_permission_data.cc b/chrome/common/extensions/permissions/usb_device_permission_data.cc index e684f4c..ce7d3d7 100644 --- a/chrome/common/extensions/permissions/usb_device_permission_data.cc +++ b/chrome/common/extensions/permissions/usb_device_permission_data.cc @@ -19,18 +19,22 @@ namespace { const char* kProductIdKey = "productId"; const char* kVendorIdKey = "vendorId"; +const char* kInterfaceIdKey = "interfaceId"; } // namespace namespace extensions { UsbDevicePermissionData::UsbDevicePermissionData() - : vendor_id_(0), product_id_(0) { + : vendor_id_(0), product_id_(0), interface_id_(ANY_INTERFACE) { } UsbDevicePermissionData::UsbDevicePermissionData(uint16 vendor_id, - uint16 product_id) - : vendor_id_(vendor_id), product_id_(product_id) { + uint16 product_id, + int interface_id) + : vendor_id_(vendor_id), + product_id_(product_id), + interface_id_(interface_id) { } bool UsbDevicePermissionData::Check( @@ -40,13 +44,15 @@ bool UsbDevicePermissionData::Check( const UsbDevicePermission::CheckParam& specific_param = *static_cast<const UsbDevicePermission::CheckParam*>(param); return vendor_id_ == specific_param.vendor_id && - product_id_ == specific_param.product_id; + product_id_ == specific_param.product_id && + interface_id_ == specific_param.interface_id; } scoped_ptr<base::Value> UsbDevicePermissionData::ToValue() const { base::DictionaryValue* result = new base::DictionaryValue(); result->SetInteger(kVendorIdKey, vendor_id_); result->SetInteger(kProductIdKey, product_id_); + result->SetInteger(kInterfaceIdKey, interface_id_); return scoped_ptr<base::Value>(result); } @@ -71,19 +77,30 @@ bool UsbDevicePermissionData::FromValue(const base::Value* value) { return false; product_id_ = temp; + if (!dict_value->GetInteger(kInterfaceIdKey, &temp)) + interface_id_ = ANY_INTERFACE; + else + interface_id_ = temp; + return true; } bool UsbDevicePermissionData::operator<( const UsbDevicePermissionData& rhs) const { - if (vendor_id_ == rhs.vendor_id_) + if (vendor_id_ == rhs.vendor_id_) { + if (product_id_ == rhs.product_id_) + return interface_id_ < rhs.interface_id_; + return product_id_ < rhs.product_id_; + } return vendor_id_ < rhs.vendor_id_; } bool UsbDevicePermissionData::operator==( const UsbDevicePermissionData& rhs) const { - return vendor_id_ == rhs.vendor_id_ && product_id_ == rhs.product_id_; + return vendor_id_ == rhs.vendor_id_ && + product_id_ == rhs.product_id_ && + interface_id_ == rhs.interface_id_; } } // namespace extensions diff --git a/chrome/common/extensions/permissions/usb_device_permission_data.h b/chrome/common/extensions/permissions/usb_device_permission_data.h index 305bc92..fa9b733 100644 --- a/chrome/common/extensions/permissions/usb_device_permission_data.h +++ b/chrome/common/extensions/permissions/usb_device_permission_data.h @@ -23,8 +23,17 @@ namespace extensions { // productId are decimal strings representing uint16 values. class UsbDevicePermissionData { public: + enum SpecialInterfaces { + // A special interface id for stating permissions for an entire USB device, + // no specific interface. This value must match value of Rule::ANY_INTERFACE + // from ChromeOS permission_broker project. + ANY_INTERFACE = -1 + }; + UsbDevicePermissionData(); - UsbDevicePermissionData(uint16 vendor_id, uint16 product_id); + UsbDevicePermissionData(uint16 vendor_id, + uint16 product_id, + int interface_id); // Check if |param| (which must be a UsbDevicePermissionData::CheckParam) // matches the vendor and product IDs associated with |this|. @@ -50,6 +59,7 @@ class UsbDevicePermissionData { private: uint16 vendor_id_; uint16 product_id_; + int interface_id_; }; } // namespace extensions diff --git a/chrome/common/extensions/permissions/usb_device_permission_unittest.cc b/chrome/common/extensions/permissions/usb_device_permission_unittest.cc index 9be0809..6728ca1 100644 --- a/chrome/common/extensions/permissions/usb_device_permission_unittest.cc +++ b/chrome/common/extensions/permissions/usb_device_permission_unittest.cc @@ -19,10 +19,12 @@ namespace extensions { TEST(USBDevicePermissionTest, PermissionDataOrder) { - EXPECT_LT(UsbDevicePermissionData(0x02ad, 0x138c), - UsbDevicePermissionData(0x02ad, 0x138d)); - ASSERT_LT(UsbDevicePermissionData(0x02ad, 0x138d), - UsbDevicePermissionData(0x02ae, 0x138c)); + EXPECT_LT(UsbDevicePermissionData(0x02ad, 0x138c, -1), + UsbDevicePermissionData(0x02ad, 0x138d, -1)); + ASSERT_LT(UsbDevicePermissionData(0x02ad, 0x138d, -1), + UsbDevicePermissionData(0x02ae, 0x138c, -1)); + EXPECT_LT(UsbDevicePermissionData(0x02ad, 0x138c, -1), + UsbDevicePermissionData(0x02ad, 0x138c, 0)); } #if defined(ENABLE_EXTENSIONS) @@ -41,11 +43,11 @@ TEST(USBDevicePermissionTest, MAYBE_PermissionMessage) { // Prepare data set scoped_ptr<base::ListValue> permission_list(new base::ListValue()); permission_list->Append( - UsbDevicePermissionData(0x02ad, 0x138c).ToValue()->DeepCopy()); + UsbDevicePermissionData(0x02ad, 0x138c, -1).ToValue()->DeepCopy()); permission_list->Append( - UsbDevicePermissionData(0x02ad, 0x138d).ToValue()->DeepCopy()); + UsbDevicePermissionData(0x02ad, 0x138d, -1).ToValue()->DeepCopy()); permission_list->Append( - UsbDevicePermissionData(0x02ae, 0x138d).ToValue()->DeepCopy()); + UsbDevicePermissionData(0x02ae, 0x138d, -1).ToValue()->DeepCopy()); UsbDevicePermission permission( PermissionsInfo::GetInstance()->GetByID(APIPermission::kUsbDevice)); diff --git a/chromeos/dbus/permission_broker_client.cc b/chromeos/dbus/permission_broker_client.cc index 294d1fb..cd86eba 100644 --- a/chromeos/dbus/permission_broker_client.cc +++ b/chromeos/dbus/permission_broker_client.cc @@ -28,11 +28,13 @@ class PermissionBrokerClientImpl : public PermissionBrokerClient { weak_ptr_factory_(this) {} virtual void RequestPathAccess(const std::string& path, + const int interface_id, const ResultCallback& callback) OVERRIDE { dbus::MethodCall method_call(kPermissionBrokerInterface, kRequestPathAccess); dbus::MessageWriter writer(&method_call); writer.AppendString(path); + writer.AppendInt32(interface_id); proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::Bind(&PermissionBrokerClientImpl::OnResponse, @@ -41,11 +43,13 @@ class PermissionBrokerClientImpl : public PermissionBrokerClient { virtual void RequestUsbAccess(const uint16_t vendor_id, const uint16_t product_id, + const int interface_id, const ResultCallback& callback) OVERRIDE { dbus::MethodCall method_call(kPermissionBrokerInterface, kRequestUsbAccess); dbus::MessageWriter writer(&method_call); writer.AppendUint16(vendor_id); writer.AppendUint16(product_id); + writer.AppendInt32(interface_id); proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::Bind(&PermissionBrokerClientImpl::OnResponse, @@ -85,12 +89,14 @@ class PermissionBrokerClientStubImpl : public PermissionBrokerClient { virtual ~PermissionBrokerClientStubImpl() {} virtual void RequestPathAccess(const std::string& path, + int interface_id, const ResultCallback& callback) OVERRIDE { callback.Run(false); } virtual void RequestUsbAccess(const uint16_t vendor_id, const uint16_t product_id, + int interface_id, const ResultCallback& callback) OVERRIDE { callback.Run(false); } diff --git a/chromeos/dbus/permission_broker_client.h b/chromeos/dbus/permission_broker_client.h index 4674cfa..645bcca 100644 --- a/chromeos/dbus/permission_broker_client.h +++ b/chromeos/dbus/permission_broker_client.h @@ -38,16 +38,25 @@ class CHROMEOS_EXPORT PermissionBrokerClient { dbus::Bus* bus); // RequestPathAccess requests access to a single device node identified by - // |path|. + // |path|. If |interface_id| value is passed (different than + // UsbDevicePermissionData::ANY_INTERFACE), the request will check if a + // specific interface is claimed while requesting access. + // This allows devices with multiple interfaces to be accessed even if + // some of them are already claimed by kernel. virtual void RequestPathAccess(const std::string& path, + int interface_id, const ResultCallback& callback) = 0; // RequestUsbAccess attempts to request access to _all_ USB devices attached - // to the system that match |vendor_id| and |product_id|. This call makes no - // attempt to guarantee atomicity, and partial failure is indistinguishable - // from complete failure. + // to the system that match |vendor_id| and |product_id|. If |interface_id| is + // passed (not -1), the request will check if a specific interface is claimed + // while requesting access. This allows devices with multiple interfaces to be + // accessed even if some of them are already claimed by kernel. + // This call makes no attempt to guarantee atomicity, and partial failure is + // indistinguishable from complete failure. virtual void RequestUsbAccess(uint16_t vendor_id, uint16_t product_id, + int interface_id, const ResultCallback& callback) = 0; protected: |