summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/api/usb/usb_api.cc9
-rw-r--r--chrome/browser/usb/usb_service.cc2
-rw-r--r--chrome/browser/usb/usb_service.h1
-rw-r--r--chrome/common/extensions/api/usb.idl1
-rw-r--r--chrome/common/extensions/permissions/usb_device_permission.h7
-rw-r--r--chrome/common/extensions/permissions/usb_device_permission_data.cc29
-rw-r--r--chrome/common/extensions/permissions/usb_device_permission_data.h12
-rw-r--r--chrome/common/extensions/permissions/usb_device_permission_unittest.cc16
-rw-r--r--chromeos/dbus/permission_broker_client.cc6
-rw-r--r--chromeos/dbus/permission_broker_client.h17
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, &param)) {
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: