Index: chrome/browser/usb/web_usb_permission_provider.cc |
diff --git a/chrome/browser/usb/web_usb_permission_provider.cc b/chrome/browser/usb/web_usb_permission_provider.cc |
index f77232dccc6c07d05776e17289deaa023f4e909c..33e54597394cd4ee4158aba99da40b99f296ce50 100644 |
--- a/chrome/browser/usb/web_usb_permission_provider.cc |
+++ b/chrome/browser/usb/web_usb_permission_provider.cc |
@@ -11,10 +11,16 @@ |
#include "content/public/browser/render_frame_host.h" |
#include "device/core/device_client.h" |
+using device::usb::WebUsbDescriptorSet; |
+using device::usb::WebUsbConfigurationSubsetPtr; |
+using device::usb::WebUsbFunctionSubsetPtr; |
+ |
namespace { |
-bool FindOriginInDescriptorSet(const device::usb::WebUsbDescriptorSet* set, |
- const GURL& origin) { |
+bool FindOriginInDescriptorSet(const WebUsbDescriptorSet* set, |
+ const GURL& origin, |
+ const uint8_t* configuration_value, |
+ const uint8_t* interface_number) { |
if (!set) |
return false; |
for (size_t i = 0; i < set->origins.size(); ++i) { |
@@ -24,6 +30,9 @@ bool FindOriginInDescriptorSet(const device::usb::WebUsbDescriptorSet* set, |
for (size_t i = 0; i < set->configurations.size(); ++i) { |
const device::usb::WebUsbConfigurationSubsetPtr& config = |
set->configurations[i]; |
+ if (configuration_value && |
+ *configuration_value != config->configuration_value) |
+ continue; |
for (size_t j = 0; i < config->origins.size(); ++j) { |
if (origin.spec() == config->origins[j]) |
return true; |
@@ -31,6 +40,10 @@ bool FindOriginInDescriptorSet(const device::usb::WebUsbDescriptorSet* set, |
for (size_t j = 0; j < config->functions.size(); ++j) { |
const device::usb::WebUsbFunctionSubsetPtr& function = |
config->functions[j]; |
+ // TODO(reillyg): Implement support for Interface Association Descriptors |
+ // so that this check will match associated interfaces. |
+ if (interface_number && *interface_number != function->first_interface) |
+ continue; |
for (size_t k = 0; k < function->origins.size(); ++k) { |
if (origin.spec() == function->origins[k]) |
return true; |
@@ -54,7 +67,7 @@ void WebUSBPermissionProvider::Create( |
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
DCHECK(render_frame_host); |
- // The created object is strongly bound to (and owned by) the pipe. |
+ // The created object is owned by its bindings. |
new WebUSBPermissionProvider(render_frame_host, request.Pass()); |
} |
@@ -63,8 +76,11 @@ WebUSBPermissionProvider::~WebUSBPermissionProvider() {} |
WebUSBPermissionProvider::WebUSBPermissionProvider( |
content::RenderFrameHost* render_frame_host, |
mojo::InterfaceRequest<PermissionProvider> request) |
- : binding_(this, request.Pass()), |
- render_frame_host_(render_frame_host) {} |
+ : render_frame_host_(render_frame_host) { |
+ bindings_.set_connection_error_handler(base::Bind( |
+ &WebUSBPermissionProvider::OnConnectionError, base::Unretained(this))); |
+ bindings_.AddBinding(this, request.Pass()); |
+} |
void WebUSBPermissionProvider::HasDevicePermission( |
mojo::Array<device::usb::DeviceInfoPtr> requested_devices, |
@@ -75,10 +91,43 @@ void WebUSBPermissionProvider::HasDevicePermission( |
mojo::Array<mojo::String> allowed_guids(0); |
for (size_t i = 0; i < requested_devices.size(); ++i) { |
const device::usb::DeviceInfoPtr& device = requested_devices[i]; |
- if (FindOriginInDescriptorSet(device->webusb_allowed_origins.get(), |
- origin) && |
+ if (FindOriginInDescriptorSet(device->webusb_allowed_origins.get(), origin, |
+ nullptr, nullptr) && |
EnableWebUsbOnAnyOrigin()) |
allowed_guids.push_back(device->guid); |
} |
callback.Run(allowed_guids.Pass()); |
} |
+ |
+void WebUSBPermissionProvider::HasConfigurationPermission( |
+ uint8_t requested_configuration_value, |
+ device::usb::DeviceInfoPtr device, |
+ const HasInterfacePermissionCallback& callback) { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ callback.Run(FindOriginInDescriptorSet( |
+ device->webusb_allowed_origins.get(), |
+ render_frame_host_->GetLastCommittedURL().GetOrigin(), |
+ &requested_configuration_value, nullptr)); |
+} |
+ |
+void WebUSBPermissionProvider::HasInterfacePermission( |
+ uint8_t requested_interface, |
+ uint8_t configuration_value, |
+ device::usb::DeviceInfoPtr device, |
+ const HasInterfacePermissionCallback& callback) { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ callback.Run(FindOriginInDescriptorSet( |
+ device->webusb_allowed_origins.get(), |
+ render_frame_host_->GetLastCommittedURL().GetOrigin(), |
+ &configuration_value, &requested_interface)); |
+} |
+ |
+void WebUSBPermissionProvider::Bind( |
+ mojo::InterfaceRequest<device::usb::PermissionProvider> request) { |
+ bindings_.AddBinding(this, request.Pass()); |
+} |
+ |
+void WebUSBPermissionProvider::OnConnectionError() { |
+ if (bindings_.empty()) |
+ delete this; |
Ken Rockot(use gerrit already)
2015/09/28 17:43:40
Ah right - this seems like a good solution that do
|
+} |