| OLD | NEW |
| 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" |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 m_resolver->reject(USBError::take(m_resolver, e)); | 169 m_resolver->reject(USBError::take(m_resolver, e)); |
| 170 } | 170 } |
| 171 | 171 |
| 172 private: | 172 private: |
| 173 Persistent<USBDevice> m_device; | 173 Persistent<USBDevice> m_device; |
| 174 Persistent<ScriptPromiseResolver> m_resolver; | 174 Persistent<ScriptPromiseResolver> m_resolver; |
| 175 size_t m_interfaceIndex; | 175 size_t m_interfaceIndex; |
| 176 bool m_desiredState; // true: claimed, false: unclaimed | 176 bool m_desiredState; // true: claimed, false: unclaimed |
| 177 }; | 177 }; |
| 178 | 178 |
| 179 class SelectAlternateInterfacePromiseAdapter : public WebCallbacks<void, const W
ebUSBError&> { |
| 180 public: |
| 181 SelectAlternateInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResol
ver* resolver, size_t interfaceIndex, size_t alternateIndex) |
| 182 : m_device(device) |
| 183 , m_resolver(resolver) |
| 184 , m_interfaceIndex(interfaceIndex) |
| 185 , m_alternateIndex(alternateIndex) |
| 186 { |
| 187 } |
| 188 |
| 189 void onSuccess() override |
| 190 { |
| 191 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
| 192 return; |
| 193 m_device->onAlternateInterfaceSelected(true /* success */, m_interfaceIn
dex, m_alternateIndex); |
| 194 m_resolver->resolve(); |
| 195 } |
| 196 |
| 197 void onError(const WebUSBError& e) override |
| 198 { |
| 199 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
| 200 return; |
| 201 m_device->onAlternateInterfaceSelected(false /* failure */, m_interfaceI
ndex, m_alternateIndex); |
| 202 m_resolver->reject(USBError::take(m_resolver, e)); |
| 203 } |
| 204 |
| 205 private: |
| 206 Persistent<USBDevice> m_device; |
| 207 Persistent<ScriptPromiseResolver> m_resolver; |
| 208 size_t m_interfaceIndex; |
| 209 size_t m_alternateIndex; |
| 210 }; |
| 211 |
| 179 class InputTransferResult { | 212 class InputTransferResult { |
| 180 WTF_MAKE_NONCOPYABLE(InputTransferResult); | 213 WTF_MAKE_NONCOPYABLE(InputTransferResult); |
| 181 public: | 214 public: |
| 182 using WebType = OwnPtr<WebUSBTransferInfo>; | 215 using WebType = OwnPtr<WebUSBTransferInfo>; |
| 183 | 216 |
| 184 static USBInTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTr
ansferInfo> webTransferInfo) | 217 static USBInTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTr
ansferInfo> webTransferInfo) |
| 185 { | 218 { |
| 186 ASSERT(webTransferInfo->status.size() == 1); | 219 ASSERT(webTransferInfo->status.size() == 1); |
| 187 return USBInTransferResult::create(convertTransferStatus(webTransferInfo
->status[0]), webTransferInfo->data); | 220 return USBInTransferResult::create(convertTransferStatus(webTransferInfo
->status[0]), webTransferInfo->data); |
| 188 } | 221 } |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 | 330 |
| 298 void USBDevice::onConfigurationSelected(bool success, size_t configurationIndex) | 331 void USBDevice::onConfigurationSelected(bool success, size_t configurationIndex) |
| 299 { | 332 { |
| 300 if (success) { | 333 if (success) { |
| 301 m_configurationIndex = configurationIndex; | 334 m_configurationIndex = configurationIndex; |
| 302 size_t numInterfaces = info().configurations[m_configurationIndex].inter
faces.size(); | 335 size_t numInterfaces = info().configurations[m_configurationIndex].inter
faces.size(); |
| 303 m_claimedInterfaces.clearAll(); | 336 m_claimedInterfaces.clearAll(); |
| 304 m_claimedInterfaces.resize(numInterfaces); | 337 m_claimedInterfaces.resize(numInterfaces); |
| 305 m_interfaceStateChangeInProgress.clearAll(); | 338 m_interfaceStateChangeInProgress.clearAll(); |
| 306 m_interfaceStateChangeInProgress.resize(numInterfaces); | 339 m_interfaceStateChangeInProgress.resize(numInterfaces); |
| 340 m_selectedAlternates.resize(numInterfaces); |
| 341 m_selectedAlternates.fill(0); |
| 307 } | 342 } |
| 308 m_deviceStateChangeInProgress = false; | 343 m_deviceStateChangeInProgress = false; |
| 309 } | 344 } |
| 310 | 345 |
| 311 void USBDevice::onInterfaceClaimedOrUnclaimed(bool claimed, size_t interfaceInde
x) | 346 void USBDevice::onInterfaceClaimedOrUnclaimed(bool claimed, size_t interfaceInde
x) |
| 312 { | 347 { |
| 313 if (claimed) | 348 if (claimed) |
| 314 m_claimedInterfaces.set(interfaceIndex); | 349 m_claimedInterfaces.set(interfaceIndex); |
| 315 else | 350 else |
| 316 m_claimedInterfaces.clear(interfaceIndex); | 351 m_claimedInterfaces.clear(interfaceIndex); |
| 317 m_interfaceStateChangeInProgress.clear(interfaceIndex); | 352 m_interfaceStateChangeInProgress.clear(interfaceIndex); |
| 318 } | 353 } |
| 319 | 354 |
| 355 void USBDevice::onAlternateInterfaceSelected(bool success, size_t interfaceIndex
, size_t alternateIndex) |
| 356 { |
| 357 if (success) |
| 358 m_selectedAlternates[interfaceIndex] = alternateIndex; |
| 359 m_interfaceStateChangeInProgress.clear(interfaceIndex); |
| 360 } |
| 361 |
| 320 bool USBDevice::isInterfaceClaimed(size_t configurationIndex, size_t interfaceIn
dex) const | 362 bool USBDevice::isInterfaceClaimed(size_t configurationIndex, size_t interfaceIn
dex) const |
| 321 { | 363 { |
| 322 return m_configurationIndex != -1 && static_cast<size_t>(m_configurationInde
x) == configurationIndex && m_claimedInterfaces.get(interfaceIndex); | 364 return m_configurationIndex != -1 && static_cast<size_t>(m_configurationInde
x) == configurationIndex && m_claimedInterfaces.get(interfaceIndex); |
| 323 } | 365 } |
| 324 | 366 |
| 367 size_t USBDevice::selectedAlternateInterface(size_t interfaceIndex) const |
| 368 { |
| 369 return m_selectedAlternates[interfaceIndex]; |
| 370 } |
| 371 |
| 325 USBConfiguration* USBDevice::configuration() const | 372 USBConfiguration* USBDevice::configuration() const |
| 326 { | 373 { |
| 327 if (m_configurationIndex != -1) | 374 if (m_configurationIndex != -1) |
| 328 return USBConfiguration::create(this, m_configurationIndex); | 375 return USBConfiguration::create(this, m_configurationIndex); |
| 329 return nullptr; | 376 return nullptr; |
| 330 } | 377 } |
| 331 | 378 |
| 332 HeapVector<Member<USBConfiguration>> USBDevice::configurations() const | 379 HeapVector<Member<USBConfiguration>> USBDevice::configurations() const |
| 333 { | 380 { |
| 334 HeapVector<Member<USBConfiguration>> configurations; | 381 HeapVector<Member<USBConfiguration>> configurations; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 } else if (!m_claimedInterfaces.get(interfaceIndex)) { | 470 } else if (!m_claimedInterfaces.get(interfaceIndex)) { |
| 424 resolver->resolve(); | 471 resolver->resolve(); |
| 425 } else { | 472 } else { |
| 426 m_interfaceStateChangeInProgress.set(interfaceIndex); | 473 m_interfaceStateChangeInProgress.set(interfaceIndex); |
| 427 m_device->releaseInterface(interfaceNumber, new ClaimInterfacePromis
eAdapter(this, resolver, interfaceIndex, false /* release */)); | 474 m_device->releaseInterface(interfaceNumber, new ClaimInterfacePromis
eAdapter(this, resolver, interfaceIndex, false /* release */)); |
| 428 } | 475 } |
| 429 } | 476 } |
| 430 return promise; | 477 return promise; |
| 431 } | 478 } |
| 432 | 479 |
| 433 ScriptPromise USBDevice::setInterface(ScriptState* scriptState, uint8_t interfac
eNumber, uint8_t alternateSetting) | 480 ScriptPromise USBDevice::selectAlternateInterface(ScriptState* scriptState, uint
8_t interfaceNumber, uint8_t alternateSetting) |
| 434 { | 481 { |
| 435 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 482 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
| 436 ScriptPromise promise = resolver->promise(); | 483 ScriptPromise promise = resolver->promise(); |
| 437 if (ensureInterfaceClaimed(interfaceNumber, resolver)) | 484 if (ensureInterfaceClaimed(interfaceNumber, resolver)) { |
| 438 m_device->setInterface(interfaceNumber, alternateSetting, new CallbackPr
omiseAdapter<void, USBError>(resolver)); | 485 // TODO(reillyg): This is duplicated work. |
| 486 int interfaceIndex = findInterfaceIndex(interfaceNumber); |
| 487 ASSERT(interfaceIndex != -1); |
| 488 int alternateIndex = findAlternateIndex(interfaceIndex, alternateSetting
); |
| 489 if (alternateIndex == -1) { |
| 490 resolver->reject(DOMException::create(NotFoundError, "The alternate
setting provided is not supported by the device in its current configuration."))
; |
| 491 } else { |
| 492 m_interfaceStateChangeInProgress.set(interfaceIndex); |
| 493 m_device->setInterface(interfaceNumber, alternateSetting, new Select
AlternateInterfacePromiseAdapter(this, resolver, interfaceIndex, alternateIndex)
); |
| 494 } |
| 495 } |
| 439 return promise; | 496 return promise; |
| 440 } | 497 } |
| 441 | 498 |
| 442 ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo
ntrolTransferParameters& setup, unsigned length) | 499 ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo
ntrolTransferParameters& setup, unsigned length) |
| 443 { | 500 { |
| 444 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 501 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
| 445 ScriptPromise promise = resolver->promise(); | 502 ScriptPromise promise = resolver->promise(); |
| 446 if (ensureDeviceConfigured(resolver)) { | 503 if (ensureDeviceConfigured(resolver)) { |
| 447 WebUSBDevice::ControlTransferParameters parameters; | 504 WebUSBDevice::ControlTransferParameters parameters; |
| 448 DOMException* error = convertControlTransferParameters(WebUSBDevice::Tra
nsferDirection::In, setup, ¶meters); | 505 DOMException* error = convertControlTransferParameters(WebUSBDevice::Tra
nsferDirection::In, setup, ¶meters); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 { | 630 { |
| 574 ASSERT(m_configurationIndex != -1); | 631 ASSERT(m_configurationIndex != -1); |
| 575 const auto& interfaces = info().configurations[m_configurationIndex].interfa
ces; | 632 const auto& interfaces = info().configurations[m_configurationIndex].interfa
ces; |
| 576 for (size_t i = 0; i < interfaces.size(); ++i) { | 633 for (size_t i = 0; i < interfaces.size(); ++i) { |
| 577 if (interfaces[i].interfaceNumber == interfaceNumber) | 634 if (interfaces[i].interfaceNumber == interfaceNumber) |
| 578 return i; | 635 return i; |
| 579 } | 636 } |
| 580 return -1; | 637 return -1; |
| 581 } | 638 } |
| 582 | 639 |
| 640 int USBDevice::findAlternateIndex(size_t interfaceIndex, uint8_t alternateSettin
g) const |
| 641 { |
| 642 ASSERT(m_configurationIndex != -1); |
| 643 const auto& alternates = info().configurations[m_configurationIndex].interfa
ces[interfaceIndex].alternates; |
| 644 for (size_t i = 0; i < alternates.size(); ++i) { |
| 645 if (alternates[i].alternateSetting == alternateSetting) |
| 646 return i; |
| 647 } |
| 648 return -1; |
| 649 } |
| 650 |
| 583 bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver*
resolver) const | 651 bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver*
resolver) const |
| 584 { | 652 { |
| 585 if (m_deviceStateChangeInProgress) { | 653 if (m_deviceStateChangeInProgress) { |
| 586 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha
ngeInProgress)); | 654 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha
ngeInProgress)); |
| 587 } else if (anyInterfaceChangeInProgress()) { | 655 } else if (anyInterfaceChangeInProgress()) { |
| 588 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState
ChangeInProgress)); | 656 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState
ChangeInProgress)); |
| 589 } else { | 657 } else { |
| 590 return true; | 658 return true; |
| 591 } | 659 } |
| 592 return false; | 660 return false; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 bool USBDevice::anyInterfaceChangeInProgress() const | 701 bool USBDevice::anyInterfaceChangeInProgress() const |
| 634 { | 702 { |
| 635 for (size_t i = 0; i < m_interfaceStateChangeInProgress.size(); ++i) { | 703 for (size_t i = 0; i < m_interfaceStateChangeInProgress.size(); ++i) { |
| 636 if (m_interfaceStateChangeInProgress.quickGet(i)) | 704 if (m_interfaceStateChangeInProgress.quickGet(i)) |
| 637 return true; | 705 return true; |
| 638 } | 706 } |
| 639 return false; | 707 return false; |
| 640 } | 708 } |
| 641 | 709 |
| 642 } // namespace blink | 710 } // namespace blink |
| OLD | NEW |