Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(323)

Side by Side Diff: third_party/WebKit/Source/modules/webusb/USB.cpp

Issue 2815003005: Integrate WebUSB with Feature Policy (Closed)
Patch Set: Ready for review Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "modules/webusb/USB.h" 5 #include "modules/webusb/USB.h"
6 6
7 #include "bindings/core/v8/ScriptPromise.h" 7 #include "bindings/core/v8/ScriptPromise.h"
8 #include "bindings/core/v8/ScriptPromiseResolver.h" 8 #include "bindings/core/v8/ScriptPromiseResolver.h"
9 #include "core/dom/DOMException.h" 9 #include "core/dom/DOMException.h"
10 #include "core/dom/Document.h" 10 #include "core/dom/Document.h"
(...skipping 10 matching lines...) Expand all
21 #include "public/platform/InterfaceProvider.h" 21 #include "public/platform/InterfaceProvider.h"
22 #include "public/platform/Platform.h" 22 #include "public/platform/Platform.h"
23 23
24 using device::mojom::blink::UsbDeviceFilterPtr; 24 using device::mojom::blink::UsbDeviceFilterPtr;
25 using device::mojom::blink::UsbDeviceInfoPtr; 25 using device::mojom::blink::UsbDeviceInfoPtr;
26 using device::mojom::blink::UsbDevicePtr; 26 using device::mojom::blink::UsbDevicePtr;
27 27
28 namespace blink { 28 namespace blink {
29 namespace { 29 namespace {
30 30
31 const char kFeaturePolicyBlocked[] =
32 "Access to the feature \"usb\" is disallowed by feature policy.";
33 const char kIframeBlocked[] =
34 "Access to this method is not allowed in embedded frames.";
31 const char kNoDeviceSelected[] = "No device selected."; 35 const char kNoDeviceSelected[] = "No device selected.";
32 36
33 UsbDeviceFilterPtr ConvertDeviceFilter(const USBDeviceFilter& filter) { 37 UsbDeviceFilterPtr ConvertDeviceFilter(const USBDeviceFilter& filter) {
34 auto mojo_filter = device::mojom::blink::UsbDeviceFilter::New(); 38 auto mojo_filter = device::mojom::blink::UsbDeviceFilter::New();
35 mojo_filter->has_vendor_id = filter.hasVendorId(); 39 mojo_filter->has_vendor_id = filter.hasVendorId();
36 if (mojo_filter->has_vendor_id) 40 if (mojo_filter->has_vendor_id)
37 mojo_filter->vendor_id = filter.vendorId(); 41 mojo_filter->vendor_id = filter.vendorId();
38 mojo_filter->has_product_id = filter.hasProductId(); 42 mojo_filter->has_product_id = filter.hasProductId();
39 if (mojo_filter->has_product_id) 43 if (mojo_filter->has_product_id)
40 mojo_filter->product_id = filter.productId(); 44 mojo_filter->product_id = filter.productId();
(...skipping 24 matching lines...) Expand all
65 DCHECK(chooser_service_requests_.IsEmpty()); 69 DCHECK(chooser_service_requests_.IsEmpty());
66 } 70 }
67 71
68 void USB::Dispose() { 72 void USB::Dispose() {
69 // The pipe to this object must be closed when is marked unreachable to 73 // The pipe to this object must be closed when is marked unreachable to
70 // prevent messages from being dispatched before lazy sweeping. 74 // prevent messages from being dispatched before lazy sweeping.
71 client_binding_.Close(); 75 client_binding_.Close();
72 } 76 }
73 77
74 ScriptPromise USB::getDevices(ScriptState* script_state) { 78 ScriptPromise USB::getDevices(ScriptState* script_state) {
79 LocalFrame* frame = GetFrame();
80 if (!frame) {
81 return ScriptPromise::RejectWithDOMException(
82 script_state, DOMException::Create(kNotSupportedError));
83 }
84
85 if (RuntimeEnabledFeatures::featurePolicyEnabled()) {
86 if (!frame->IsFeatureEnabled(WebFeaturePolicyFeature::kUsb)) {
87 return ScriptPromise::RejectWithDOMException(
88 script_state,
89 DOMException::Create(kSecurityError, kFeaturePolicyBlocked));
90 }
91 } else if (!frame->IsMainFrame()) {
92 return ScriptPromise::RejectWithDOMException(
93 script_state, DOMException::Create(kSecurityError, kIframeBlocked));
94 }
95
96 EnsureDeviceManagerConnection();
75 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); 97 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
76 ScriptPromise promise = resolver->Promise(); 98 device_manager_requests_.insert(resolver);
77 EnsureDeviceManagerConnection(); 99 device_manager_->GetDevices(
78 if (!device_manager_) { 100 nullptr,
79 resolver->Reject(DOMException::Create(kNotSupportedError)); 101 ConvertToBaseCallback(WTF::Bind(&USB::OnGetDevices, WrapPersistent(this),
80 } else { 102 WrapPersistent(resolver))));
81 device_manager_requests_.insert(resolver); 103 return resolver->Promise();
82 device_manager_->GetDevices(
83 nullptr, ConvertToBaseCallback(WTF::Bind(&USB::OnGetDevices,
84 WrapPersistent(this),
85 WrapPersistent(resolver))));
86 }
87 return promise;
88 } 104 }
89 105
90 ScriptPromise USB::requestDevice(ScriptState* script_state, 106 ScriptPromise USB::requestDevice(ScriptState* script_state,
91 const USBDeviceRequestOptions& options) { 107 const USBDeviceRequestOptions& options) {
92 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); 108 LocalFrame* frame = GetFrame();
93 ScriptPromise promise = resolver->Promise(); 109 if (!frame) {
110 return ScriptPromise::RejectWithDOMException(
111 script_state, DOMException::Create(kNotSupportedError));
112 }
113
114 if (RuntimeEnabledFeatures::featurePolicyEnabled()) {
115 if (!frame->IsFeatureEnabled(WebFeaturePolicyFeature::kUsb)) {
116 return ScriptPromise::RejectWithDOMException(
117 script_state,
118 DOMException::Create(kSecurityError, kFeaturePolicyBlocked));
119 }
120 } else if (!frame->IsMainFrame()) {
121 return ScriptPromise::RejectWithDOMException(
122 script_state, DOMException::Create(kSecurityError, kIframeBlocked));
123 }
94 124
95 if (!chooser_service_) { 125 if (!chooser_service_) {
96 if (!GetFrame()) {
97 resolver->Reject(DOMException::Create(kNotSupportedError));
98 return promise;
99 }
100 GetFrame()->GetInterfaceProvider()->GetInterface( 126 GetFrame()->GetInterfaceProvider()->GetInterface(
101 mojo::MakeRequest(&chooser_service_)); 127 mojo::MakeRequest(&chooser_service_));
102 chooser_service_.set_connection_error_handler( 128 chooser_service_.set_connection_error_handler(
103 ConvertToBaseCallback(WTF::Bind(&USB::OnChooserServiceConnectionError, 129 ConvertToBaseCallback(WTF::Bind(&USB::OnChooserServiceConnectionError,
104 WrapWeakPersistent(this)))); 130 WrapWeakPersistent(this))));
105 } 131 }
106 132
107 if (!UserGestureIndicator::ConsumeUserGesture()) { 133 if (!UserGestureIndicator::ConsumeUserGesture()) {
108 resolver->Reject(DOMException::Create( 134 return ScriptPromise::RejectWithDOMException(
109 kSecurityError, 135 script_state,
110 "Must be handling a user gesture to show a permission request.")); 136 DOMException::Create(
111 } else { 137 kSecurityError,
112 Vector<UsbDeviceFilterPtr> filters; 138 "Must be handling a user gesture to show a permission request."));
113 if (options.hasFilters()) {
114 filters.ReserveCapacity(options.filters().size());
115 for (const auto& filter : options.filters())
116 filters.push_back(ConvertDeviceFilter(filter));
117 }
118 chooser_service_requests_.insert(resolver);
119 chooser_service_->GetPermission(
120 std::move(filters), ConvertToBaseCallback(WTF::Bind(
121 &USB::OnGetPermission, WrapPersistent(this),
122 WrapPersistent(resolver))));
123 } 139 }
124 return promise; 140
141 Vector<UsbDeviceFilterPtr> filters;
142 if (options.hasFilters()) {
143 filters.ReserveCapacity(options.filters().size());
144 for (const auto& filter : options.filters())
145 filters.push_back(ConvertDeviceFilter(filter));
146 }
147
148 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
149 chooser_service_requests_.insert(resolver);
150 chooser_service_->GetPermission(
151 std::move(filters), ConvertToBaseCallback(WTF::Bind(
152 &USB::OnGetPermission, WrapPersistent(this),
153 WrapPersistent(resolver))));
154 return resolver->Promise();
125 } 155 }
126 156
127 ExecutionContext* USB::GetExecutionContext() const { 157 ExecutionContext* USB::GetExecutionContext() const {
128 return ContextLifecycleObserver::GetExecutionContext(); 158 return ContextLifecycleObserver::GetExecutionContext();
129 } 159 }
130 160
131 const AtomicString& USB::InterfaceName() const { 161 const AtomicString& USB::InterfaceName() const {
132 return EventTargetNames::USB; 162 return EventTargetNames::USB;
133 } 163 }
134 164
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 198
169 void USB::OnGetPermission(ScriptPromiseResolver* resolver, 199 void USB::OnGetPermission(ScriptPromiseResolver* resolver,
170 UsbDeviceInfoPtr device_info) { 200 UsbDeviceInfoPtr device_info) {
171 auto request_entry = chooser_service_requests_.find(resolver); 201 auto request_entry = chooser_service_requests_.find(resolver);
172 if (request_entry == chooser_service_requests_.end()) 202 if (request_entry == chooser_service_requests_.end())
173 return; 203 return;
174 chooser_service_requests_.erase(request_entry); 204 chooser_service_requests_.erase(request_entry);
175 205
176 EnsureDeviceManagerConnection(); 206 EnsureDeviceManagerConnection();
177 207
178 if (device_manager_ && device_info) { 208 if (device_manager_ && device_info)
179 resolver->Resolve(GetOrCreateDevice(std::move(device_info))); 209 resolver->Resolve(GetOrCreateDevice(std::move(device_info)));
180 } else { 210 else
181 resolver->Reject(DOMException::Create(kNotFoundError, kNoDeviceSelected)); 211 resolver->Reject(DOMException::Create(kNotFoundError, kNoDeviceSelected));
182 }
183 } 212 }
184 213
185 void USB::OnDeviceAdded(UsbDeviceInfoPtr device_info) { 214 void USB::OnDeviceAdded(UsbDeviceInfoPtr device_info) {
186 if (!device_manager_) 215 if (!device_manager_)
187 return; 216 return;
188 217
189 DispatchEvent(USBConnectionEvent::Create( 218 DispatchEvent(USBConnectionEvent::Create(
190 EventTypeNames::connect, GetOrCreateDevice(std::move(device_info)))); 219 EventTypeNames::connect, GetOrCreateDevice(std::move(device_info))));
191 } 220 }
192 221
(...skipping 19 matching lines...) Expand all
212 void USB::OnChooserServiceConnectionError() { 241 void USB::OnChooserServiceConnectionError() {
213 chooser_service_.reset(); 242 chooser_service_.reset();
214 for (ScriptPromiseResolver* resolver : chooser_service_requests_) 243 for (ScriptPromiseResolver* resolver : chooser_service_requests_)
215 resolver->Reject(DOMException::Create(kNotFoundError, kNoDeviceSelected)); 244 resolver->Reject(DOMException::Create(kNotFoundError, kNoDeviceSelected));
216 chooser_service_requests_.clear(); 245 chooser_service_requests_.clear();
217 } 246 }
218 247
219 void USB::AddedEventListener(const AtomicString& event_type, 248 void USB::AddedEventListener(const AtomicString& event_type,
220 RegisteredEventListener& listener) { 249 RegisteredEventListener& listener) {
221 EventTargetWithInlineData::AddedEventListener(event_type, listener); 250 EventTargetWithInlineData::AddedEventListener(event_type, listener);
222 if (event_type == EventTypeNames::connect || 251 if (event_type != EventTypeNames::connect &&
223 event_type == EventTypeNames::disconnect) { 252 event_type != EventTypeNames::disconnect) {
253 return;
254 }
255
256 LocalFrame* frame = GetFrame();
257 if (!frame)
258 return;
259
260 if (RuntimeEnabledFeatures::featurePolicyEnabled()) {
261 if (frame->IsFeatureEnabled(WebFeaturePolicyFeature::kUsb))
262 EnsureDeviceManagerConnection();
263 } else if (frame->IsMainFrame()) {
224 EnsureDeviceManagerConnection(); 264 EnsureDeviceManagerConnection();
225 } 265 }
226 } 266 }
227 267
228 void USB::EnsureDeviceManagerConnection() { 268 void USB::EnsureDeviceManagerConnection() {
229 if (device_manager_ || !GetFrame()) 269 if (device_manager_)
230 return; 270 return;
231 271
272 DCHECK(GetFrame());
232 GetFrame()->GetInterfaceProvider()->GetInterface( 273 GetFrame()->GetInterfaceProvider()->GetInterface(
233 mojo::MakeRequest(&device_manager_)); 274 mojo::MakeRequest(&device_manager_));
234 device_manager_.set_connection_error_handler(ConvertToBaseCallback(WTF::Bind( 275 device_manager_.set_connection_error_handler(ConvertToBaseCallback(WTF::Bind(
235 &USB::OnDeviceManagerConnectionError, WrapWeakPersistent(this)))); 276 &USB::OnDeviceManagerConnectionError, WrapWeakPersistent(this))));
236 277
237 DCHECK(!client_binding_.is_bound()); 278 DCHECK(!client_binding_.is_bound());
238 device_manager_->SetClient(client_binding_.CreateInterfacePtrAndBind()); 279 device_manager_->SetClient(client_binding_.CreateInterfacePtrAndBind());
239 } 280 }
240 281
241 DEFINE_TRACE(USB) { 282 DEFINE_TRACE(USB) {
242 visitor->Trace(device_manager_requests_); 283 visitor->Trace(device_manager_requests_);
243 visitor->Trace(chooser_service_requests_); 284 visitor->Trace(chooser_service_requests_);
244 visitor->Trace(device_cache_); 285 visitor->Trace(device_cache_);
245 EventTargetWithInlineData::Trace(visitor); 286 EventTargetWithInlineData::Trace(visitor);
246 ContextLifecycleObserver::Trace(visitor); 287 ContextLifecycleObserver::Trace(visitor);
247 } 288 }
248 289
249 } // namespace blink 290 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698