| Index: third_party/WebKit/Source/modules/webusb/USB.cpp
|
| diff --git a/third_party/WebKit/Source/modules/webusb/USB.cpp b/third_party/WebKit/Source/modules/webusb/USB.cpp
|
| index be6863a179b610cd28f8b3216692e96c04922d4b..25480f4ccdf22759d4a5dc7487c3ae1ef7cfc84f 100644
|
| --- a/third_party/WebKit/Source/modules/webusb/USB.cpp
|
| +++ b/third_party/WebKit/Source/modules/webusb/USB.cpp
|
| @@ -28,6 +28,10 @@ using device::mojom::blink::UsbDevicePtr;
|
| namespace blink {
|
| namespace {
|
|
|
| +const char kFeaturePolicyBlocked[] =
|
| + "Access to the feature \"usb\" is disallowed by feature policy.";
|
| +const char kIframeBlocked[] =
|
| + "Access to this method is not allowed in embedded frames.";
|
| const char kNoDeviceSelected[] = "No device selected.";
|
|
|
| UsbDeviceFilterPtr ConvertDeviceFilter(const USBDeviceFilter& filter) {
|
| @@ -72,31 +76,53 @@ void USB::Dispose() {
|
| }
|
|
|
| ScriptPromise USB::getDevices(ScriptState* script_state) {
|
| - ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
|
| - ScriptPromise promise = resolver->Promise();
|
| - EnsureDeviceManagerConnection();
|
| - if (!device_manager_) {
|
| - resolver->Reject(DOMException::Create(kNotSupportedError));
|
| - } else {
|
| - device_manager_requests_.insert(resolver);
|
| - device_manager_->GetDevices(
|
| - nullptr, ConvertToBaseCallback(WTF::Bind(&USB::OnGetDevices,
|
| - WrapPersistent(this),
|
| - WrapPersistent(resolver))));
|
| + LocalFrame* frame = GetFrame();
|
| + if (!frame) {
|
| + return ScriptPromise::RejectWithDOMException(
|
| + script_state, DOMException::Create(kNotSupportedError));
|
| }
|
| - return promise;
|
| +
|
| + if (RuntimeEnabledFeatures::featurePolicyEnabled()) {
|
| + if (!frame->IsFeatureEnabled(WebFeaturePolicyFeature::kUsb)) {
|
| + return ScriptPromise::RejectWithDOMException(
|
| + script_state,
|
| + DOMException::Create(kSecurityError, kFeaturePolicyBlocked));
|
| + }
|
| + } else if (!frame->IsMainFrame()) {
|
| + return ScriptPromise::RejectWithDOMException(
|
| + script_state, DOMException::Create(kSecurityError, kIframeBlocked));
|
| + }
|
| +
|
| + EnsureDeviceManagerConnection();
|
| + ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
|
| + device_manager_requests_.insert(resolver);
|
| + device_manager_->GetDevices(
|
| + nullptr,
|
| + ConvertToBaseCallback(WTF::Bind(&USB::OnGetDevices, WrapPersistent(this),
|
| + WrapPersistent(resolver))));
|
| + return resolver->Promise();
|
| }
|
|
|
| ScriptPromise USB::requestDevice(ScriptState* script_state,
|
| const USBDeviceRequestOptions& options) {
|
| - ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
|
| - ScriptPromise promise = resolver->Promise();
|
| + LocalFrame* frame = GetFrame();
|
| + if (!frame) {
|
| + return ScriptPromise::RejectWithDOMException(
|
| + script_state, DOMException::Create(kNotSupportedError));
|
| + }
|
|
|
| - if (!chooser_service_) {
|
| - if (!GetFrame()) {
|
| - resolver->Reject(DOMException::Create(kNotSupportedError));
|
| - return promise;
|
| + if (RuntimeEnabledFeatures::featurePolicyEnabled()) {
|
| + if (!frame->IsFeatureEnabled(WebFeaturePolicyFeature::kUsb)) {
|
| + return ScriptPromise::RejectWithDOMException(
|
| + script_state,
|
| + DOMException::Create(kSecurityError, kFeaturePolicyBlocked));
|
| }
|
| + } else if (!frame->IsMainFrame()) {
|
| + return ScriptPromise::RejectWithDOMException(
|
| + script_state, DOMException::Create(kSecurityError, kIframeBlocked));
|
| + }
|
| +
|
| + if (!chooser_service_) {
|
| GetFrame()->GetInterfaceProvider()->GetInterface(
|
| mojo::MakeRequest(&chooser_service_));
|
| chooser_service_.set_connection_error_handler(
|
| @@ -105,23 +131,27 @@ ScriptPromise USB::requestDevice(ScriptState* script_state,
|
| }
|
|
|
| if (!UserGestureIndicator::ConsumeUserGesture()) {
|
| - resolver->Reject(DOMException::Create(
|
| - kSecurityError,
|
| - "Must be handling a user gesture to show a permission request."));
|
| - } else {
|
| - Vector<UsbDeviceFilterPtr> filters;
|
| - if (options.hasFilters()) {
|
| - filters.ReserveCapacity(options.filters().size());
|
| - for (const auto& filter : options.filters())
|
| - filters.push_back(ConvertDeviceFilter(filter));
|
| - }
|
| - chooser_service_requests_.insert(resolver);
|
| - chooser_service_->GetPermission(
|
| - std::move(filters), ConvertToBaseCallback(WTF::Bind(
|
| - &USB::OnGetPermission, WrapPersistent(this),
|
| - WrapPersistent(resolver))));
|
| + return ScriptPromise::RejectWithDOMException(
|
| + script_state,
|
| + DOMException::Create(
|
| + kSecurityError,
|
| + "Must be handling a user gesture to show a permission request."));
|
| + }
|
| +
|
| + Vector<UsbDeviceFilterPtr> filters;
|
| + if (options.hasFilters()) {
|
| + filters.ReserveCapacity(options.filters().size());
|
| + for (const auto& filter : options.filters())
|
| + filters.push_back(ConvertDeviceFilter(filter));
|
| }
|
| - return promise;
|
| +
|
| + ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
|
| + chooser_service_requests_.insert(resolver);
|
| + chooser_service_->GetPermission(
|
| + std::move(filters), ConvertToBaseCallback(WTF::Bind(
|
| + &USB::OnGetPermission, WrapPersistent(this),
|
| + WrapPersistent(resolver))));
|
| + return resolver->Promise();
|
| }
|
|
|
| ExecutionContext* USB::GetExecutionContext() const {
|
| @@ -175,11 +205,10 @@ void USB::OnGetPermission(ScriptPromiseResolver* resolver,
|
|
|
| EnsureDeviceManagerConnection();
|
|
|
| - if (device_manager_ && device_info) {
|
| + if (device_manager_ && device_info)
|
| resolver->Resolve(GetOrCreateDevice(std::move(device_info)));
|
| - } else {
|
| + else
|
| resolver->Reject(DOMException::Create(kNotFoundError, kNoDeviceSelected));
|
| - }
|
| }
|
|
|
| void USB::OnDeviceAdded(UsbDeviceInfoPtr device_info) {
|
| @@ -219,16 +248,28 @@ void USB::OnChooserServiceConnectionError() {
|
| void USB::AddedEventListener(const AtomicString& event_type,
|
| RegisteredEventListener& listener) {
|
| EventTargetWithInlineData::AddedEventListener(event_type, listener);
|
| - if (event_type == EventTypeNames::connect ||
|
| - event_type == EventTypeNames::disconnect) {
|
| + if (event_type != EventTypeNames::connect &&
|
| + event_type != EventTypeNames::disconnect) {
|
| + return;
|
| + }
|
| +
|
| + LocalFrame* frame = GetFrame();
|
| + if (!frame)
|
| + return;
|
| +
|
| + if (RuntimeEnabledFeatures::featurePolicyEnabled()) {
|
| + if (frame->IsFeatureEnabled(WebFeaturePolicyFeature::kUsb))
|
| + EnsureDeviceManagerConnection();
|
| + } else if (frame->IsMainFrame()) {
|
| EnsureDeviceManagerConnection();
|
| }
|
| }
|
|
|
| void USB::EnsureDeviceManagerConnection() {
|
| - if (device_manager_ || !GetFrame())
|
| + if (device_manager_)
|
| return;
|
|
|
| + DCHECK(GetFrame());
|
| GetFrame()->GetInterfaceProvider()->GetInterface(
|
| mojo::MakeRequest(&device_manager_));
|
| device_manager_.set_connection_error_handler(ConvertToBaseCallback(WTF::Bind(
|
|
|