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

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: Fix webexposed test. 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, int 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 int m_configurationIndex;
144 }; 144 };
145 145
146 class ClaimInterfacePromiseAdapter : public WebCallbacks<void, const WebUSBError &> {
juncai 2016/03/17 01:21:11 Is class ClaimInterfacePromiseAdapter used anywher
juncai 2016/03/17 05:59:34 ah, please ignore this comment. I just realized th
Reilly Grant (use Gerrit) 2016/03/17 17:07:01 It is used in claimInterface and releaseInterface.
147 public:
148 ClaimInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resol ver, int 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 int m_interfaceIndex;
176 bool m_desiredState; // true: claimed, false: unclaimed
177 };
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);
154 return USBInTransferResult::create(convertTransferStatus(webTransferInfo ->status[0]), webTransferInfo->data); 187 return USBInTransferResult::create(convertTransferStatus(webTransferInfo ->status[0]), webTransferInfo->data);
155 } 188 }
(...skipping 86 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, configurationIndex);
juncai 2016/03/17 01:21:11 nit: add comment for true parameter.
Reilly Grant (use Gerrit) 2016/03/17 17:07:01 Done.
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, int 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, int interfaceIndex)
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 (m_deviceStateChangeInProgress) {
290 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); 346 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress));
347 } else if (anyInterfaceChangeInProgress()) {
348 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress));
juncai 2016/03/17 01:21:11 USBDevice::open, USBDevice::close and USBDevice::s
Reilly Grant (use Gerrit) 2016/03/17 17:07:01 Done.
291 } else if (m_opened) { 349 } else if (m_opened) {
292 resolver->resolve(); 350 resolver->resolve();
293 } else { 351 } else {
294 m_deviceStateChangeInProgress = true; 352 m_deviceStateChangeInProgress = true;
295 m_device->open(new OpenClosePromiseAdapter(this, resolver, true /* open */)); 353 m_device->open(new OpenClosePromiseAdapter(this, resolver, true /* open */));
296 } 354 }
297 return promise; 355 return promise;
298 } 356 }
299 357
300 ScriptPromise USBDevice::close(ScriptState* scriptState) 358 ScriptPromise USBDevice::close(ScriptState* scriptState)
301 { 359 {
302 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 360 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
303 ScriptPromise promise = resolver->promise(); 361 ScriptPromise promise = resolver->promise();
304 if (m_deviceStateChangeInProgress) { 362 if (m_deviceStateChangeInProgress) {
305 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); 363 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress));
364 } else if (anyInterfaceChangeInProgress()) {
365 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress));
306 } else if (!m_opened) { 366 } else if (!m_opened) {
307 resolver->resolve(); 367 resolver->resolve();
308 } else { 368 } else {
309 m_deviceStateChangeInProgress = true; 369 m_deviceStateChangeInProgress = true;
310 m_device->close(new OpenClosePromiseAdapter(this, resolver, false /* clo sed */)); 370 m_device->close(new OpenClosePromiseAdapter(this, resolver, false /* clo sed */));
311 } 371 }
312 return promise; 372 return promise;
313 } 373 }
314 374
315 ScriptPromise USBDevice::selectConfiguration(ScriptState* scriptState, uint8_t c onfigurationValue) 375 ScriptPromise USBDevice::selectConfiguration(ScriptState* scriptState, uint8_t c onfigurationValue)
316 { 376 {
317 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 377 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
318 ScriptPromise promise = resolver->promise(); 378 ScriptPromise promise = resolver->promise();
319 if (!m_opened) { 379 if (!m_opened) {
320 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ; 380 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ;
321 } else if (m_deviceStateChangeInProgress) { 381 } else if (m_deviceStateChangeInProgress) {
322 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); 382 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress));
383 } else if (anyInterfaceChangeInProgress()) {
384 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress));
323 } else { 385 } else {
324 int configurationIndex = findConfigurationIndex(configurationValue); 386 int configurationIndex = findConfigurationIndex(configurationValue);
325 if (configurationIndex == -1) { 387 if (configurationIndex == -1) {
326 resolver->reject(DOMException::create(NotFoundError, "The configurat ion value provided is not supported by the device.")); 388 resolver->reject(DOMException::create(NotFoundError, "The configurat ion value provided is not supported by the device."));
327 } else if (m_configurationIndex == configurationIndex) { 389 } else if (m_configurationIndex == configurationIndex) {
328 resolver->resolve(); 390 resolver->resolve();
329 } else { 391 } else {
330 m_deviceStateChangeInProgress = true; 392 m_deviceStateChangeInProgress = true;
331 m_device->setConfiguration(configurationValue, new SelectConfigurati onPromiseAdapter(this, resolver, configurationIndex)); 393 m_device->setConfiguration(configurationValue, new SelectConfigurati onPromiseAdapter(this, resolver, configurationIndex));
332 } 394 }
333 } 395 }
334 return promise; 396 return promise;
335 } 397 }
336 398
337 ScriptPromise USBDevice::claimInterface(ScriptState* scriptState, uint8_t interf aceNumber) 399 ScriptPromise USBDevice::claimInterface(ScriptState* scriptState, uint8_t interf aceNumber)
338 { 400 {
339 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 401 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
340 ScriptPromise promise = resolver->promise(); 402 ScriptPromise promise = resolver->promise();
341 if (ensureDeviceConfigured(resolver)) 403 if (ensureDeviceConfigured(resolver)) {
342 m_device->claimInterface(interfaceNumber, new CallbackPromiseAdapter<voi d, USBError>(resolver)); 404 int interfaceIndex = findInterfaceIndex(interfaceNumber);
405 if (interfaceIndex == -1) {
406 resolver->reject(DOMException::create(NotFoundError, kInterfaceNotFo und));
407 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) {
juncai 2016/03/17 01:21:11 Use static_cast<size_t>(interfaceIndex) since: get
Reilly Grant (use Gerrit) 2016/03/17 17:07:01 Done.
408 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS tateChangeInProgress));
409 } else if (m_claimedInterfaces.get(interfaceIndex)) {
410 resolver->resolve();
411 } else {
412 m_interfaceStateChangeInProgress.set(interfaceIndex);
413 m_device->claimInterface(interfaceNumber, new ClaimInterfacePromiseA dapter(this, resolver, interfaceIndex, true));
414 }
415 }
343 return promise; 416 return promise;
344 } 417 }
345 418
346 ScriptPromise USBDevice::releaseInterface(ScriptState* scriptState, uint8_t inte rfaceNumber) 419 ScriptPromise USBDevice::releaseInterface(ScriptState* scriptState, uint8_t inte rfaceNumber)
347 { 420 {
348 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 421 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
349 ScriptPromise promise = resolver->promise(); 422 ScriptPromise promise = resolver->promise();
350 if (ensureDeviceConfigured(resolver)) 423 if (ensureDeviceConfigured(resolver)) {
351 m_device->releaseInterface(interfaceNumber, new CallbackPromiseAdapter<v oid, USBError>(resolver)); 424 int interfaceIndex = findInterfaceIndex(interfaceNumber);
425 if (interfaceIndex == -1) {
426 resolver->reject(DOMException::create(NotFoundError, "The interface number provided is not supported by the device in its current configuration."));
427 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) {
428 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS tateChangeInProgress));
429 } else if (!m_claimedInterfaces.get(interfaceIndex)) {
430 resolver->resolve();
431 } else {
432 m_interfaceStateChangeInProgress.set(interfaceIndex);
433 m_device->releaseInterface(interfaceNumber, new ClaimInterfacePromis eAdapter(this, resolver, interfaceIndex, false));
434 }
435 }
352 return promise; 436 return promise;
353 } 437 }
354 438
355 ScriptPromise USBDevice::setInterface(ScriptState* scriptState, uint8_t interfac eNumber, uint8_t alternateSetting) 439 ScriptPromise USBDevice::setInterface(ScriptState* scriptState, uint8_t interfac eNumber, uint8_t alternateSetting)
356 { 440 {
357 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 441 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
358 ScriptPromise promise = resolver->promise(); 442 ScriptPromise promise = resolver->promise();
359 if (ensureDeviceConfigured(resolver)) 443 if (ensureInterfaceClaimed(interfaceNumber, resolver))
360 m_device->setInterface(interfaceNumber, alternateSetting, new CallbackPr omiseAdapter<void, USBError>(resolver)); 444 m_device->setInterface(interfaceNumber, alternateSetting, new CallbackPr omiseAdapter<void, USBError>(resolver));
361 return promise; 445 return promise;
362 } 446 }
363 447
364 ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo ntrolTransferParameters& setup, unsigned length) 448 ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo ntrolTransferParameters& setup, unsigned length)
365 { 449 {
366 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 450 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
367 ScriptPromise promise = resolver->promise(); 451 ScriptPromise promise = resolver->promise();
368 if (ensureDeviceConfigured(resolver)) { 452 if (ensureDeviceConfigured(resolver)) {
369 WebUSBDevice::ControlTransferParameters parameters; 453 WebUSBDevice::ControlTransferParameters parameters;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 if (error) { 485 if (error) {
402 resolver->reject(error); 486 resolver->reject(error);
403 } else { 487 } else {
404 BufferSource buffer(data); 488 BufferSource buffer(data);
405 m_device->controlTransfer(parameters, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver)); 489 m_device->controlTransfer(parameters, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver));
406 } 490 }
407 } 491 }
408 return promise; 492 return promise;
409 } 493 }
410 494
411 ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, uint8_t endpointNum ber) 495 ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, String direction, u int8_t endpointNumber)
412 { 496 {
413 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 497 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
414 ScriptPromise promise = resolver->promise(); 498 ScriptPromise promise = resolver->promise();
415 if (ensureDeviceConfigured(resolver)) 499 if (ensureEndpointAvailable(direction == "in", endpointNumber, resolver))
416 m_device->clearHalt(endpointNumber, new CallbackPromiseAdapter<void, USB Error>(resolver)); 500 m_device->clearHalt(endpointNumber, new CallbackPromiseAdapter<void, USB Error>(resolver));
417 return promise; 501 return promise;
418 } 502 }
419 503
420 ScriptPromise USBDevice::transferIn(ScriptState* scriptState, uint8_t endpointNu mber, unsigned length) 504 ScriptPromise USBDevice::transferIn(ScriptState* scriptState, uint8_t endpointNu mber, unsigned length)
421 { 505 {
422 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 506 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
423 ScriptPromise promise = resolver->promise(); 507 ScriptPromise promise = resolver->promise();
424 if (ensureDeviceConfigured(resolver)) 508 if (ensureEndpointAvailable(true, endpointNumber, resolver))
425 m_device->transfer(WebUSBDevice::TransferDirection::In, endpointNumber, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(re solver)); 509 m_device->transfer(WebUSBDevice::TransferDirection::In, endpointNumber, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(re solver));
426 return promise; 510 return promise;
427 } 511 }
428 512
429 ScriptPromise USBDevice::transferOut(ScriptState* scriptState, uint8_t endpointN umber, const ArrayBufferOrArrayBufferView& data) 513 ScriptPromise USBDevice::transferOut(ScriptState* scriptState, uint8_t endpointN umber, const ArrayBufferOrArrayBufferView& data)
430 { 514 {
431 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 515 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
432 ScriptPromise promise = resolver->promise(); 516 ScriptPromise promise = resolver->promise();
433 if (ensureDeviceConfigured(resolver)) { 517 if (ensureEndpointAvailable(false, endpointNumber, resolver)) {
434 BufferSource buffer(data); 518 BufferSource buffer(data);
435 m_device->transfer(WebUSBDevice::TransferDirection::Out, endpointNumber, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResul t, USBError>(resolver)); 519 m_device->transfer(WebUSBDevice::TransferDirection::Out, endpointNumber, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResul t, USBError>(resolver));
436 } 520 }
437 return promise; 521 return promise;
438 } 522 }
439 523
440 ScriptPromise USBDevice::isochronousTransferIn(ScriptState* scriptState, uint8_t endpointNumber, Vector<unsigned> packetLengths) 524 ScriptPromise USBDevice::isochronousTransferIn(ScriptState* scriptState, uint8_t endpointNumber, Vector<unsigned> packetLengths)
441 { 525 {
442 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 526 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
443 ScriptPromise promise = resolver->promise(); 527 ScriptPromise promise = resolver->promise();
444 if (ensureDeviceConfigured(resolver)) 528 if (ensureEndpointAvailable(true, endpointNumber, resolver))
445 m_device->isochronousTransfer(WebUSBDevice::TransferDirection::In, endpo intNumber, nullptr, 0, packetLengths, 0, new CallbackPromiseAdapter<IsochronousI nputTransferResult, USBError>(resolver)); 529 m_device->isochronousTransfer(WebUSBDevice::TransferDirection::In, endpo intNumber, nullptr, 0, packetLengths, 0, new CallbackPromiseAdapter<IsochronousI nputTransferResult, USBError>(resolver));
446 return promise; 530 return promise;
447 } 531 }
448 532
449 ScriptPromise USBDevice::isochronousTransferOut(ScriptState* scriptState, uint8_ t endpointNumber, const ArrayBufferOrArrayBufferView& data, Vector<unsigned> pac ketLengths) 533 ScriptPromise USBDevice::isochronousTransferOut(ScriptState* scriptState, uint8_ t endpointNumber, const ArrayBufferOrArrayBufferView& data, Vector<unsigned> pac ketLengths)
450 { 534 {
451 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 535 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
452 ScriptPromise promise = resolver->promise(); 536 ScriptPromise promise = resolver->promise();
453 if (ensureDeviceConfigured(resolver)) { 537 if (ensureEndpointAvailable(false, endpointNumber, resolver)) {
454 BufferSource buffer(data); 538 BufferSource buffer(data);
455 m_device->isochronousTransfer(WebUSBDevice::TransferDirection::Out, endp ointNumber, buffer.data(), buffer.size(), packetLengths, 0, new CallbackPromiseA dapter<IsochronousOutputTransferResult, USBError>(resolver)); 539 m_device->isochronousTransfer(WebUSBDevice::TransferDirection::Out, endp ointNumber, buffer.data(), buffer.size(), packetLengths, 0, new CallbackPromiseA dapter<IsochronousOutputTransferResult, USBError>(resolver));
456 } 540 }
457 return promise; 541 return promise;
458 } 542 }
459 543
460 ScriptPromise USBDevice::reset(ScriptState* scriptState) 544 ScriptPromise USBDevice::reset(ScriptState* scriptState)
461 { 545 {
462 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 546 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
463 ScriptPromise promise = resolver->promise(); 547 ScriptPromise promise = resolver->promise();
(...skipping 20 matching lines...) Expand all
484 int USBDevice::findConfigurationIndex(uint8_t configurationValue) const 568 int USBDevice::findConfigurationIndex(uint8_t configurationValue) const
485 { 569 {
486 const auto& configurations = info().configurations; 570 const auto& configurations = info().configurations;
487 for (size_t i = 0; i < configurations.size(); ++i) { 571 for (size_t i = 0; i < configurations.size(); ++i) {
488 if (configurations[i].configurationValue == configurationValue) 572 if (configurations[i].configurationValue == configurationValue)
489 return i; 573 return i;
490 } 574 }
491 return -1; 575 return -1;
492 } 576 }
493 577
578 int USBDevice::findInterfaceIndex(uint8_t interfaceNumber) const
juncai 2016/03/17 01:21:11 This function may need to return size_t.
Reilly Grant (use Gerrit) 2016/03/17 17:07:01 It can't return -1 if it returns size_t.
579 {
580 ASSERT(m_configurationIndex != -1);
581 const auto& interfaces = info().configurations[m_configurationIndex].interfa ces;
582 for (size_t i = 0; i < interfaces.size(); ++i) {
583 if (interfaces[i].interfaceNumber == interfaceNumber)
584 return i;
585 }
586 return -1;
587 }
588
494 bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const 589 bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const
495 { 590 {
496 if (!m_opened) { 591 if (!m_opened) {
497 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ; 592 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ;
498 } else if (m_deviceStateChangeInProgress) { 593 } else if (m_deviceStateChangeInProgress) {
499 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); 594 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress));
500 } else if (m_configurationIndex == -1) { 595 } else if (m_configurationIndex == -1) {
501 resolver->reject(DOMException::create(InvalidStateError, "The device mus t have a configuration selected.")); 596 resolver->reject(DOMException::create(InvalidStateError, "The device mus t have a configuration selected."));
502 } else { 597 } else {
503 return true; 598 return true;
504 } 599 }
505 return false; 600 return false;
506 } 601 }
507 602
603 bool USBDevice::ensureInterfaceClaimed(uint8_t interfaceNumber, ScriptPromiseRes olver* resolver) const
604 {
605 if (!ensureDeviceConfigured(resolver))
606 return false;
607 int interfaceIndex = findInterfaceIndex(interfaceNumber);
608 if (interfaceIndex == -1) {
609 resolver->reject(DOMException::create(NotFoundError, kInterfaceNotFound) );
610 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) {
611 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress));
612 } else if (!m_claimedInterfaces.get(interfaceIndex)) {
613 resolver->reject(DOMException::create(InvalidStateError, "The specified interface has not been claimed."));
614 } else {
615 return true;
616 }
617 return false;
618 }
619
620 bool USBDevice::ensureEndpointAvailable(bool inTransfer, uint8_t endpointNumber, ScriptPromiseResolver* resolver) const
621 {
622 // TODO(reillyg): Check endpoint availability once Blink is tracking which
623 // alternate interfaces are selected.
624 return ensureDeviceConfigured(resolver);
625 }
626
627 bool USBDevice::anyInterfaceChangeInProgress() const
628 {
629 for (size_t i = 0; i < m_interfaceStateChangeInProgress.size(); ++i) {
630 if (m_interfaceStateChangeInProgress.quickGet(i))
631 return true;
632 }
633 return false;
634 }
635
508 } // namespace blink 636 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698