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

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

Issue 1814603002: Track USB device interface claim state in Blink. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed juncai@'s comments. Created 4 years, 9 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/USBDevice.h" 5 #include "modules/webusb/USBDevice.h"
6 6
7 #include "bindings/core/v8/CallbackPromiseAdapter.h" 7 #include "bindings/core/v8/CallbackPromiseAdapter.h"
8 #include "bindings/core/v8/ScriptPromise.h" 8 #include "bindings/core/v8/ScriptPromise.h"
9 #include "bindings/core/v8/ScriptPromiseResolver.h" 9 #include "bindings/core/v8/ScriptPromiseResolver.h"
10 #include "bindings/core/v8/ToV8.h" 10 #include "bindings/core/v8/ToV8.h"
11 #include "core/dom/DOMArrayBuffer.h" 11 #include "core/dom/DOMArrayBuffer.h"
12 #include "core/dom/DOMArrayBufferView.h" 12 #include "core/dom/DOMArrayBufferView.h"
13 #include "core/dom/DOMException.h" 13 #include "core/dom/DOMException.h"
14 #include "core/dom/ExceptionCode.h" 14 #include "core/dom/ExceptionCode.h"
15 #include "modules/webusb/USBConfiguration.h" 15 #include "modules/webusb/USBConfiguration.h"
16 #include "modules/webusb/USBControlTransferParameters.h" 16 #include "modules/webusb/USBControlTransferParameters.h"
17 #include "modules/webusb/USBError.h" 17 #include "modules/webusb/USBError.h"
18 #include "modules/webusb/USBInTransferResult.h" 18 #include "modules/webusb/USBInTransferResult.h"
19 #include "modules/webusb/USBIsochronousInTransferResult.h" 19 #include "modules/webusb/USBIsochronousInTransferResult.h"
20 #include "modules/webusb/USBIsochronousOutTransferResult.h" 20 #include "modules/webusb/USBIsochronousOutTransferResult.h"
21 #include "modules/webusb/USBOutTransferResult.h" 21 #include "modules/webusb/USBOutTransferResult.h"
22 #include "public/platform/modules/webusb/WebUSBTransferInfo.h" 22 #include "public/platform/modules/webusb/WebUSBTransferInfo.h"
23 #include "wtf/Assertions.h" 23 #include "wtf/Assertions.h"
24 24
25 namespace blink { 25 namespace blink {
26 26
27 namespace { 27 namespace {
28 28
29 const char kDeviceStateChangeInProgress[] = "An operation that changes the devic e state is in progress."; 29 const char kDeviceStateChangeInProgress[] = "An operation that changes the devic e state is in progress.";
30 const char kInterfaceNotFound[] = "The interface number provided is not supporte d by the device in its current configuration.";
31 const char kInterfaceStateChangeInProgress[] = "An operation that changes interf ace state is in progress.";
30 const char kOpenRequired[] = "The device must be opened first."; 32 const char kOpenRequired[] = "The device must be opened first.";
31 33
32 DOMException* convertControlTransferParameters( 34 DOMException* convertControlTransferParameters(
33 WebUSBDevice::TransferDirection direction, 35 WebUSBDevice::TransferDirection direction,
34 const USBControlTransferParameters& parameters, 36 const USBControlTransferParameters& parameters,
35 WebUSBDevice::ControlTransferParameters* webParameters) 37 WebUSBDevice::ControlTransferParameters* webParameters)
36 { 38 {
37 webParameters->direction = direction; 39 webParameters->direction = direction;
38 40
39 if (parameters.requestType() == "standard") 41 if (parameters.requestType() == "standard")
40 webParameters->type = WebUSBDevice::RequestType::Standard; 42 webParameters->type = WebUSBDevice::RequestType::Standard;
41 else if (parameters.requestType() == "class") 43 else if (parameters.requestType() == "class")
42 webParameters->type = WebUSBDevice::RequestType::Class; 44 webParameters->type = WebUSBDevice::RequestType::Class;
43 else if (parameters.requestType() == "vendor") 45 else if (parameters.requestType() == "vendor")
44 webParameters->type = WebUSBDevice::RequestType::Vendor; 46 webParameters->type = WebUSBDevice::RequestType::Vendor;
45 else 47 else
46 return DOMException::create(TypeMismatchError, "The control transfer req uestType parameter is invalid."); 48 return DOMException::create(TypeMismatchError, "The control transfer req uestType parameter is invalid.");
47 49
50 // TODO(reillyg): Check for interface and endpoint availability if that is
51 // the control transfer target.
48 if (parameters.recipient() == "device") 52 if (parameters.recipient() == "device")
49 webParameters->recipient = WebUSBDevice::RequestRecipient::Device; 53 webParameters->recipient = WebUSBDevice::RequestRecipient::Device;
50 else if (parameters.recipient() == "interface") 54 else if (parameters.recipient() == "interface")
51 webParameters->recipient = WebUSBDevice::RequestRecipient::Interface; 55 webParameters->recipient = WebUSBDevice::RequestRecipient::Interface;
52 else if (parameters.recipient() == "endpoint") 56 else if (parameters.recipient() == "endpoint")
53 webParameters->recipient = WebUSBDevice::RequestRecipient::Endpoint; 57 webParameters->recipient = WebUSBDevice::RequestRecipient::Endpoint;
54 else if (parameters.recipient() == "other") 58 else if (parameters.recipient() == "other")
55 webParameters->recipient = WebUSBDevice::RequestRecipient::Other; 59 webParameters->recipient = WebUSBDevice::RequestRecipient::Other;
56 else 60 else
57 return DOMException::create(TypeMismatchError, "The control transfer rec ipient parameter is invalid."); 61 return DOMException::create(TypeMismatchError, "The control transfer rec ipient parameter is invalid.");
(...skipping 25 matching lines...) Expand all
83 : m_device(device) 87 : m_device(device)
84 , m_resolver(resolver) 88 , m_resolver(resolver)
85 , m_desiredState(desiredState) 89 , m_desiredState(desiredState)
86 { 90 {
87 } 91 }
88 92
89 void onSuccess() override 93 void onSuccess() override
90 { 94 {
91 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) 95 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped())
92 return; 96 return;
93 if (m_device) 97 m_device->onDeviceOpenedOrClosed(m_desiredState);
94 m_device->onDeviceOpenedOrClosed(m_desiredState);
95 m_resolver->resolve(); 98 m_resolver->resolve();
96 } 99 }
97 100
98 void onError(const WebUSBError& e) override 101 void onError(const WebUSBError& e) override
99 { 102 {
100 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) 103 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped())
101 return; 104 return;
102 if (m_device) 105 m_device->onDeviceOpenedOrClosed(!m_desiredState);
103 m_device->onDeviceOpenedOrClosed(!m_desiredState);
104 m_resolver->reject(USBError::take(m_resolver, e)); 106 m_resolver->reject(USBError::take(m_resolver, e));
105 } 107 }
106 108
107 private: 109 private:
108 WeakPersistent<USBDevice> m_device; 110 Persistent<USBDevice> m_device;
109 Persistent<ScriptPromiseResolver> m_resolver; 111 Persistent<ScriptPromiseResolver> m_resolver;
110 bool m_desiredState; // true: open, false: closed 112 bool m_desiredState; // true: open, false: closed
111 }; 113 };
112 114
113 class SelectConfigurationPromiseAdapter : public WebCallbacks<void, const WebUSB Error&> { 115 class SelectConfigurationPromiseAdapter : public WebCallbacks<void, const WebUSB Error&> {
114 public: 116 public:
115 SelectConfigurationPromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, int configurationIndex) 117 SelectConfigurationPromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, size_t configurationIndex)
116 : m_device(device) 118 : m_device(device)
117 , m_resolver(resolver) 119 , m_resolver(resolver)
118 , m_configurationIndex(configurationIndex) 120 , m_configurationIndex(configurationIndex)
119 { 121 {
120 } 122 }
121 123
122 void onSuccess() override 124 void onSuccess() override
123 { 125 {
124 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) 126 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped())
125 return; 127 return;
126 if (m_device) 128 m_device->onConfigurationSelected(true /* success */, m_configurationInd ex);
127 m_device->onConfigurationSelected(true /* success */, m_configuratio nIndex);
128 m_resolver->resolve(); 129 m_resolver->resolve();
129 } 130 }
130 131
131 void onError(const WebUSBError& e) override 132 void onError(const WebUSBError& e) override
132 { 133 {
133 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) 134 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped())
134 return; 135 return;
135 if (m_device) 136 m_device->onConfigurationSelected(false /* failure */, m_configurationIn dex);
136 m_device->onConfigurationSelected(false /* failure */, m_configurati onIndex);
137 m_resolver->reject(USBError::take(m_resolver, e)); 137 m_resolver->reject(USBError::take(m_resolver, e));
138 } 138 }
139 139
140 private: 140 private:
141 WeakPersistent<USBDevice> m_device; 141 Persistent<USBDevice> m_device;
142 Persistent<ScriptPromiseResolver> m_resolver; 142 Persistent<ScriptPromiseResolver> m_resolver;
143 int m_configurationIndex; 143 size_t m_configurationIndex;
144 };
145
146 class ClaimInterfacePromiseAdapter : public WebCallbacks<void, const WebUSBError &> {
147 public:
148 ClaimInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resol ver, size_t interfaceIndex, bool desiredState)
149 : m_device(device)
150 , m_resolver(resolver)
151 , m_interfaceIndex(interfaceIndex)
152 , m_desiredState(desiredState)
153 {
154 }
155
156 void onSuccess() override
157 {
158 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped())
159 return;
160 m_device->onInterfaceClaimedOrUnclaimed(m_desiredState, m_interfaceIndex );
161 m_resolver->resolve();
162 }
163
164 void onError(const WebUSBError& e) override
165 {
166 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped())
167 return;
168 m_device->onInterfaceClaimedOrUnclaimed(!m_desiredState, m_interfaceInde x);
169 m_resolver->reject(USBError::take(m_resolver, e));
170 }
171
172 private:
173 Persistent<USBDevice> m_device;
174 Persistent<ScriptPromiseResolver> m_resolver;
175 size_t m_interfaceIndex;
176 bool m_desiredState; // true: claimed, false: unclaimed
144 }; 177 };
145 178
146 class InputTransferResult { 179 class InputTransferResult {
147 WTF_MAKE_NONCOPYABLE(InputTransferResult); 180 WTF_MAKE_NONCOPYABLE(InputTransferResult);
148 public: 181 public:
149 using WebType = OwnPtr<WebUSBTransferInfo>; 182 using WebType = OwnPtr<WebUSBTransferInfo>;
150 183
151 static USBInTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTr ansferInfo> webTransferInfo) 184 static USBInTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTr ansferInfo> webTransferInfo)
152 { 185 {
153 ASSERT(webTransferInfo->status.size() == 1); 186 ASSERT(webTransferInfo->status.size() == 1);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 USBDevice* USBDevice::take(ScriptPromiseResolver* resolver, PassOwnPtr<WebUSBDev ice> device) 275 USBDevice* USBDevice::take(ScriptPromiseResolver* resolver, PassOwnPtr<WebUSBDev ice> device)
243 { 276 {
244 return USBDevice::create(device, resolver->getExecutionContext()); 277 return USBDevice::create(device, resolver->getExecutionContext());
245 } 278 }
246 279
247 USBDevice::USBDevice(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context) 280 USBDevice::USBDevice(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context)
248 : ContextLifecycleObserver(context) 281 : ContextLifecycleObserver(context)
249 , m_device(device) 282 , m_device(device)
250 , m_opened(false) 283 , m_opened(false)
251 , m_deviceStateChangeInProgress(false) 284 , m_deviceStateChangeInProgress(false)
285 , m_configurationIndex(-1)
252 { 286 {
253 m_configurationIndex = findConfigurationIndex(info().activeConfiguration); 287 int configurationIndex = findConfigurationIndex(info().activeConfiguration);
288 if (configurationIndex != -1)
289 onConfigurationSelected(true /* success */, configurationIndex);
254 } 290 }
255 291
256 void USBDevice::onDeviceOpenedOrClosed(bool opened) 292 void USBDevice::onDeviceOpenedOrClosed(bool opened)
257 { 293 {
258 m_opened = opened; 294 m_opened = opened;
259 m_deviceStateChangeInProgress = false; 295 m_deviceStateChangeInProgress = false;
260 } 296 }
261 297
262 void USBDevice::onConfigurationSelected(bool success, int configurationIndex) 298 void USBDevice::onConfigurationSelected(bool success, size_t configurationIndex)
263 { 299 {
264 if (success) 300 if (success) {
265 m_configurationIndex = configurationIndex; 301 m_configurationIndex = configurationIndex;
302 size_t numInterfaces = info().configurations[m_configurationIndex].inter faces.size();
303 m_claimedInterfaces.clearAll();
304 m_claimedInterfaces.resize(numInterfaces);
305 m_interfaceStateChangeInProgress.clearAll();
306 m_interfaceStateChangeInProgress.resize(numInterfaces);
307 }
266 m_deviceStateChangeInProgress = false; 308 m_deviceStateChangeInProgress = false;
267 } 309 }
268 310
311 void USBDevice::onInterfaceClaimedOrUnclaimed(bool claimed, size_t interfaceInde x)
312 {
313 if (claimed)
314 m_claimedInterfaces.set(interfaceIndex);
315 else
316 m_claimedInterfaces.clear(interfaceIndex);
317 m_interfaceStateChangeInProgress.clear(interfaceIndex);
318 }
319
320 bool USBDevice::isInterfaceClaimed(size_t configurationIndex, size_t interfaceIn dex) const
321 {
322 return m_configurationIndex != -1 && static_cast<size_t>(m_configurationInde x) == configurationIndex && m_claimedInterfaces.get(interfaceIndex);
323 }
324
269 USBConfiguration* USBDevice::configuration() const 325 USBConfiguration* USBDevice::configuration() const
270 { 326 {
271 if (m_configurationIndex != -1) 327 if (m_configurationIndex != -1)
272 return USBConfiguration::create(this, m_configurationIndex); 328 return USBConfiguration::create(this, m_configurationIndex);
273 return nullptr; 329 return nullptr;
274 } 330 }
275 331
276 HeapVector<Member<USBConfiguration>> USBDevice::configurations() const 332 HeapVector<Member<USBConfiguration>> USBDevice::configurations() const
277 { 333 {
278 HeapVector<Member<USBConfiguration>> configurations; 334 HeapVector<Member<USBConfiguration>> configurations;
279 size_t numConfigurations = info().configurations.size(); 335 size_t numConfigurations = info().configurations.size();
280 for (size_t i = 0; i < numConfigurations; ++i) 336 for (size_t i = 0; i < numConfigurations; ++i)
281 configurations.append(USBConfiguration::create(this, i)); 337 configurations.append(USBConfiguration::create(this, i));
282 return configurations; 338 return configurations;
283 } 339 }
284 340
285 ScriptPromise USBDevice::open(ScriptState* scriptState) 341 ScriptPromise USBDevice::open(ScriptState* scriptState)
286 { 342 {
287 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 343 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
288 ScriptPromise promise = resolver->promise(); 344 ScriptPromise promise = resolver->promise();
289 if (m_deviceStateChangeInProgress) { 345 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
290 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); 346 if (m_opened) {
291 } else if (m_opened) { 347 resolver->resolve();
292 resolver->resolve(); 348 } else {
293 } else { 349 m_deviceStateChangeInProgress = true;
294 m_deviceStateChangeInProgress = true; 350 m_device->open(new OpenClosePromiseAdapter(this, resolver, true /* o pen */));
295 m_device->open(new OpenClosePromiseAdapter(this, resolver, true /* open */)); 351 }
296 } 352 }
297 return promise; 353 return promise;
298 } 354 }
299 355
300 ScriptPromise USBDevice::close(ScriptState* scriptState) 356 ScriptPromise USBDevice::close(ScriptState* scriptState)
301 { 357 {
302 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 358 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
303 ScriptPromise promise = resolver->promise(); 359 ScriptPromise promise = resolver->promise();
304 if (m_deviceStateChangeInProgress) { 360 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
305 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); 361 if (!m_opened) {
306 } else if (!m_opened) { 362 resolver->resolve();
307 resolver->resolve(); 363 } else {
308 } else { 364 m_deviceStateChangeInProgress = true;
309 m_deviceStateChangeInProgress = true; 365 m_device->close(new OpenClosePromiseAdapter(this, resolver, false /* closed */));
310 m_device->close(new OpenClosePromiseAdapter(this, resolver, false /* clo sed */)); 366 }
311 } 367 }
312 return promise; 368 return promise;
313 } 369 }
314 370
315 ScriptPromise USBDevice::selectConfiguration(ScriptState* scriptState, uint8_t c onfigurationValue) 371 ScriptPromise USBDevice::selectConfiguration(ScriptState* scriptState, uint8_t c onfigurationValue)
316 { 372 {
317 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 373 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
318 ScriptPromise promise = resolver->promise(); 374 ScriptPromise promise = resolver->promise();
319 if (!m_opened) { 375 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
320 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ; 376 if (!m_opened) {
321 } else if (m_deviceStateChangeInProgress) { 377 resolver->reject(DOMException::create(InvalidStateError, kOpenRequir ed));
322 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress));
323 } else {
324 int configurationIndex = findConfigurationIndex(configurationValue);
325 if (configurationIndex == -1) {
326 resolver->reject(DOMException::create(NotFoundError, "The configurat ion value provided is not supported by the device."));
327 } else if (m_configurationIndex == configurationIndex) {
328 resolver->resolve();
329 } else { 378 } else {
330 m_deviceStateChangeInProgress = true; 379 int configurationIndex = findConfigurationIndex(configurationValue);
331 m_device->setConfiguration(configurationValue, new SelectConfigurati onPromiseAdapter(this, resolver, configurationIndex)); 380 if (configurationIndex == -1) {
381 resolver->reject(DOMException::create(NotFoundError, "The config uration value provided is not supported by the device."));
382 } else if (m_configurationIndex == configurationIndex) {
383 resolver->resolve();
384 } else {
385 m_deviceStateChangeInProgress = true;
386 m_device->setConfiguration(configurationValue, new SelectConfigu rationPromiseAdapter(this, resolver, configurationIndex));
387 }
332 } 388 }
333 } 389 }
334 return promise; 390 return promise;
335 } 391 }
336 392
337 ScriptPromise USBDevice::claimInterface(ScriptState* scriptState, uint8_t interf aceNumber) 393 ScriptPromise USBDevice::claimInterface(ScriptState* scriptState, uint8_t interf aceNumber)
338 { 394 {
339 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 395 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
340 ScriptPromise promise = resolver->promise(); 396 ScriptPromise promise = resolver->promise();
341 if (ensureDeviceConfigured(resolver)) 397 if (ensureDeviceConfigured(resolver)) {
342 m_device->claimInterface(interfaceNumber, new CallbackPromiseAdapter<voi d, USBError>(resolver)); 398 int interfaceIndex = findInterfaceIndex(interfaceNumber);
399 if (interfaceIndex == -1) {
400 resolver->reject(DOMException::create(NotFoundError, kInterfaceNotFo und));
401 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) {
juncai 2016/03/17 18:20:37 nit: may need to use static_cast<size_t> here sinc
Reilly Grant (use Gerrit) 2016/03/18 00:10:22 The compiler is not complaining so I'm going to le
402 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS tateChangeInProgress));
403 } else if (m_claimedInterfaces.get(interfaceIndex)) {
juncai 2016/03/17 18:20:37 ditto.
404 resolver->resolve();
405 } else {
406 m_interfaceStateChangeInProgress.set(interfaceIndex);
juncai 2016/03/17 18:20:37 ditto.
407 m_device->claimInterface(interfaceNumber, new ClaimInterfacePromiseA dapter(this, resolver, interfaceIndex, true));
juncai 2016/03/17 18:20:37 nit: may need to use static_cast<size_t> here sinc
Reilly Grant (use Gerrit) 2016/03/18 00:10:22 Done.
408 }
409 }
343 return promise; 410 return promise;
344 } 411 }
345 412
346 ScriptPromise USBDevice::releaseInterface(ScriptState* scriptState, uint8_t inte rfaceNumber) 413 ScriptPromise USBDevice::releaseInterface(ScriptState* scriptState, uint8_t inte rfaceNumber)
347 { 414 {
348 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 415 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
349 ScriptPromise promise = resolver->promise(); 416 ScriptPromise promise = resolver->promise();
350 if (ensureDeviceConfigured(resolver)) 417 if (ensureDeviceConfigured(resolver)) {
351 m_device->releaseInterface(interfaceNumber, new CallbackPromiseAdapter<v oid, USBError>(resolver)); 418 int interfaceIndex = findInterfaceIndex(interfaceNumber);
419 if (interfaceIndex == -1) {
420 resolver->reject(DOMException::create(NotFoundError, "The interface number provided is not supported by the device in its current configuration."));
421 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) {
juncai 2016/03/17 18:20:37 ditto.
422 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS tateChangeInProgress));
423 } else if (!m_claimedInterfaces.get(interfaceIndex)) {
juncai 2016/03/17 18:20:38 ditto.
424 resolver->resolve();
425 } else {
426 m_interfaceStateChangeInProgress.set(interfaceIndex);
juncai 2016/03/17 18:20:37 ditto.
427 m_device->releaseInterface(interfaceNumber, new ClaimInterfacePromis eAdapter(this, resolver, interfaceIndex, false));
juncai 2016/03/17 18:20:37 nit: may need to use static_cast<size_t> here sinc
Reilly Grant (use Gerrit) 2016/03/18 00:10:22 Done.
428 }
429 }
352 return promise; 430 return promise;
353 } 431 }
354 432
355 ScriptPromise USBDevice::setInterface(ScriptState* scriptState, uint8_t interfac eNumber, uint8_t alternateSetting) 433 ScriptPromise USBDevice::setInterface(ScriptState* scriptState, uint8_t interfac eNumber, uint8_t alternateSetting)
356 { 434 {
357 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 435 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
358 ScriptPromise promise = resolver->promise(); 436 ScriptPromise promise = resolver->promise();
359 if (ensureDeviceConfigured(resolver)) 437 if (ensureInterfaceClaimed(interfaceNumber, resolver))
360 m_device->setInterface(interfaceNumber, alternateSetting, new CallbackPr omiseAdapter<void, USBError>(resolver)); 438 m_device->setInterface(interfaceNumber, alternateSetting, new CallbackPr omiseAdapter<void, USBError>(resolver));
361 return promise; 439 return promise;
362 } 440 }
363 441
364 ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo ntrolTransferParameters& setup, unsigned length) 442 ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo ntrolTransferParameters& setup, unsigned length)
365 { 443 {
366 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 444 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
367 ScriptPromise promise = resolver->promise(); 445 ScriptPromise promise = resolver->promise();
368 if (ensureDeviceConfigured(resolver)) { 446 if (ensureDeviceConfigured(resolver)) {
369 WebUSBDevice::ControlTransferParameters parameters; 447 WebUSBDevice::ControlTransferParameters parameters;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 if (error) { 479 if (error) {
402 resolver->reject(error); 480 resolver->reject(error);
403 } else { 481 } else {
404 BufferSource buffer(data); 482 BufferSource buffer(data);
405 m_device->controlTransfer(parameters, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver)); 483 m_device->controlTransfer(parameters, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver));
406 } 484 }
407 } 485 }
408 return promise; 486 return promise;
409 } 487 }
410 488
411 ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, uint8_t endpointNum ber) 489 ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, String direction, u int8_t endpointNumber)
412 { 490 {
413 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 491 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
414 ScriptPromise promise = resolver->promise(); 492 ScriptPromise promise = resolver->promise();
415 if (ensureDeviceConfigured(resolver)) 493 if (ensureEndpointAvailable(direction == "in", endpointNumber, resolver))
416 m_device->clearHalt(endpointNumber, new CallbackPromiseAdapter<void, USB Error>(resolver)); 494 m_device->clearHalt(endpointNumber, new CallbackPromiseAdapter<void, USB Error>(resolver));
417 return promise; 495 return promise;
418 } 496 }
419 497
420 ScriptPromise USBDevice::transferIn(ScriptState* scriptState, uint8_t endpointNu mber, unsigned length) 498 ScriptPromise USBDevice::transferIn(ScriptState* scriptState, uint8_t endpointNu mber, unsigned length)
421 { 499 {
422 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 500 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
423 ScriptPromise promise = resolver->promise(); 501 ScriptPromise promise = resolver->promise();
424 if (ensureDeviceConfigured(resolver)) 502 if (ensureEndpointAvailable(true, endpointNumber, resolver))
juncai 2016/03/17 18:20:38 nit: add comments for true parameter.
Reilly Grant (use Gerrit) 2016/03/18 00:10:22 Done.
425 m_device->transfer(WebUSBDevice::TransferDirection::In, endpointNumber, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(re solver)); 503 m_device->transfer(WebUSBDevice::TransferDirection::In, endpointNumber, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(re solver));
426 return promise; 504 return promise;
427 } 505 }
428 506
429 ScriptPromise USBDevice::transferOut(ScriptState* scriptState, uint8_t endpointN umber, const ArrayBufferOrArrayBufferView& data) 507 ScriptPromise USBDevice::transferOut(ScriptState* scriptState, uint8_t endpointN umber, const ArrayBufferOrArrayBufferView& data)
430 { 508 {
431 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 509 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
432 ScriptPromise promise = resolver->promise(); 510 ScriptPromise promise = resolver->promise();
433 if (ensureDeviceConfigured(resolver)) { 511 if (ensureEndpointAvailable(false, endpointNumber, resolver)) {
juncai 2016/03/17 18:20:37 nit: add comments for false parameter.
Reilly Grant (use Gerrit) 2016/03/18 00:10:22 Done.
434 BufferSource buffer(data); 512 BufferSource buffer(data);
435 m_device->transfer(WebUSBDevice::TransferDirection::Out, endpointNumber, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResul t, USBError>(resolver)); 513 m_device->transfer(WebUSBDevice::TransferDirection::Out, endpointNumber, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResul t, USBError>(resolver));
436 } 514 }
437 return promise; 515 return promise;
438 } 516 }
439 517
440 ScriptPromise USBDevice::isochronousTransferIn(ScriptState* scriptState, uint8_t endpointNumber, Vector<unsigned> packetLengths) 518 ScriptPromise USBDevice::isochronousTransferIn(ScriptState* scriptState, uint8_t endpointNumber, Vector<unsigned> packetLengths)
441 { 519 {
442 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 520 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
443 ScriptPromise promise = resolver->promise(); 521 ScriptPromise promise = resolver->promise();
444 if (ensureDeviceConfigured(resolver)) 522 if (ensureEndpointAvailable(true, endpointNumber, resolver))
juncai 2016/03/17 18:20:37 nit: add comments for true parameter.
Reilly Grant (use Gerrit) 2016/03/18 00:10:22 Done.
445 m_device->isochronousTransfer(WebUSBDevice::TransferDirection::In, endpo intNumber, nullptr, 0, packetLengths, 0, new CallbackPromiseAdapter<IsochronousI nputTransferResult, USBError>(resolver)); 523 m_device->isochronousTransfer(WebUSBDevice::TransferDirection::In, endpo intNumber, nullptr, 0, packetLengths, 0, new CallbackPromiseAdapter<IsochronousI nputTransferResult, USBError>(resolver));
446 return promise; 524 return promise;
447 } 525 }
448 526
449 ScriptPromise USBDevice::isochronousTransferOut(ScriptState* scriptState, uint8_ t endpointNumber, const ArrayBufferOrArrayBufferView& data, Vector<unsigned> pac ketLengths) 527 ScriptPromise USBDevice::isochronousTransferOut(ScriptState* scriptState, uint8_ t endpointNumber, const ArrayBufferOrArrayBufferView& data, Vector<unsigned> pac ketLengths)
450 { 528 {
451 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 529 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
452 ScriptPromise promise = resolver->promise(); 530 ScriptPromise promise = resolver->promise();
453 if (ensureDeviceConfigured(resolver)) { 531 if (ensureEndpointAvailable(false, endpointNumber, resolver)) {
juncai 2016/03/17 18:20:37 nit: add comments for false parameter.
Reilly Grant (use Gerrit) 2016/03/18 00:10:22 Done.
454 BufferSource buffer(data); 532 BufferSource buffer(data);
455 m_device->isochronousTransfer(WebUSBDevice::TransferDirection::Out, endp ointNumber, buffer.data(), buffer.size(), packetLengths, 0, new CallbackPromiseA dapter<IsochronousOutputTransferResult, USBError>(resolver)); 533 m_device->isochronousTransfer(WebUSBDevice::TransferDirection::Out, endp ointNumber, buffer.data(), buffer.size(), packetLengths, 0, new CallbackPromiseA dapter<IsochronousOutputTransferResult, USBError>(resolver));
456 } 534 }
457 return promise; 535 return promise;
458 } 536 }
459 537
460 ScriptPromise USBDevice::reset(ScriptState* scriptState) 538 ScriptPromise USBDevice::reset(ScriptState* scriptState)
461 { 539 {
462 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 540 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
463 ScriptPromise promise = resolver->promise(); 541 ScriptPromise promise = resolver->promise();
464 if (!m_opened) 542 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
465 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ; 543 if (!m_opened)
466 else if (m_deviceStateChangeInProgress) 544 resolver->reject(DOMException::create(InvalidStateError, kOpenRequir ed));
467 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); 545 else
468 else 546 m_device->reset(new CallbackPromiseAdapter<void, USBError>(resolver) );
469 m_device->reset(new CallbackPromiseAdapter<void, USBError>(resolver)); 547 }
470 return promise; 548 return promise;
471 } 549 }
472 550
473 void USBDevice::contextDestroyed() 551 void USBDevice::contextDestroyed()
474 { 552 {
475 if (m_opened) 553 if (m_opened)
476 m_device->close(new WebUSBDeviceCloseCallbacks()); 554 m_device->close(new WebUSBDeviceCloseCallbacks());
477 } 555 }
478 556
479 DEFINE_TRACE(USBDevice) 557 DEFINE_TRACE(USBDevice)
480 { 558 {
481 ContextLifecycleObserver::trace(visitor); 559 ContextLifecycleObserver::trace(visitor);
482 } 560 }
483 561
484 int USBDevice::findConfigurationIndex(uint8_t configurationValue) const 562 int USBDevice::findConfigurationIndex(uint8_t configurationValue) const
485 { 563 {
486 const auto& configurations = info().configurations; 564 const auto& configurations = info().configurations;
487 for (size_t i = 0; i < configurations.size(); ++i) { 565 for (size_t i = 0; i < configurations.size(); ++i) {
488 if (configurations[i].configurationValue == configurationValue) 566 if (configurations[i].configurationValue == configurationValue)
489 return i; 567 return i;
490 } 568 }
491 return -1; 569 return -1;
492 } 570 }
493 571
572 int USBDevice::findInterfaceIndex(uint8_t interfaceNumber) const
573 {
574 ASSERT(m_configurationIndex != -1);
575 const auto& interfaces = info().configurations[m_configurationIndex].interfa ces;
576 for (size_t i = 0; i < interfaces.size(); ++i) {
577 if (interfaces[i].interfaceNumber == interfaceNumber)
578 return i;
juncai 2016/03/17 18:20:38 nit: static_cast<int>(i) since i is size_t type.
579 }
580 return -1;
581 }
582
583 bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver* resolver) const
584 {
585 if (m_deviceStateChangeInProgress) {
586 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress));
587 } else if (anyInterfaceChangeInProgress()) {
588 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress));
589 } else {
590 return true;
591 }
592 return false;
593 }
594
494 bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const 595 bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const
495 { 596 {
496 if (!m_opened) { 597 if (!m_opened) {
497 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ; 598 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ;
498 } else if (m_deviceStateChangeInProgress) { 599 } else if (m_deviceStateChangeInProgress) {
499 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); 600 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress));
500 } else if (m_configurationIndex == -1) { 601 } else if (m_configurationIndex == -1) {
501 resolver->reject(DOMException::create(InvalidStateError, "The device mus t have a configuration selected.")); 602 resolver->reject(DOMException::create(InvalidStateError, "The device mus t have a configuration selected."));
502 } else { 603 } else {
503 return true; 604 return true;
504 } 605 }
505 return false; 606 return false;
506 } 607 }
507 608
609 bool USBDevice::ensureInterfaceClaimed(uint8_t interfaceNumber, ScriptPromiseRes olver* resolver) const
610 {
611 if (!ensureDeviceConfigured(resolver))
612 return false;
613 int interfaceIndex = findInterfaceIndex(interfaceNumber);
614 if (interfaceIndex == -1) {
615 resolver->reject(DOMException::create(NotFoundError, kInterfaceNotFound) );
616 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) {
juncai 2016/03/17 18:20:37 nit: may need to use static_cast<size_t> here sinc
617 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress));
618 } else if (!m_claimedInterfaces.get(interfaceIndex)) {
juncai 2016/03/17 18:20:38 ditto.
619 resolver->reject(DOMException::create(InvalidStateError, "The specified interface has not been claimed."));
620 } else {
621 return true;
622 }
623 return false;
624 }
625
626 bool USBDevice::ensureEndpointAvailable(bool inTransfer, uint8_t endpointNumber, ScriptPromiseResolver* resolver) const
627 {
628 // TODO(reillyg): Check endpoint availability once Blink is tracking which
629 // alternate interfaces are selected.
630 return ensureDeviceConfigured(resolver);
631 }
632
633 bool USBDevice::anyInterfaceChangeInProgress() const
634 {
635 for (size_t i = 0; i < m_interfaceStateChangeInProgress.size(); ++i) {
636 if (m_interfaceStateChangeInProgress.quickGet(i))
637 return true;
638 }
639 return false;
640 }
641
508 } // namespace blink 642 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698