| 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 14 matching lines...) Expand all Loading... |
| 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."; | 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."; | 31 const char kInterfaceStateChangeInProgress[] = "An operation that changes interf
ace state is in progress."; |
| 32 const char kOpenRequired[] = "The device must be opened first."; | 32 const char kOpenRequired[] = "The device must be opened first."; |
| 33 const char kVisibiltyError[] = "Connection is only allowed while the page is vis
ible. This is a temporary measure until we are able to effectively communicate t
o the user that the page is connected to a device."; | 33 const char kVisibiltyError[] = "Connection is only allowed while the page is vis
ible. This is a temporary measure until we are able to effectively communicate t
o the user that the page is connected to a device."; |
| 34 | 34 |
| 35 DOMException* convertControlTransferParameters( | |
| 36 WebUSBDevice::TransferDirection direction, | |
| 37 const USBControlTransferParameters& parameters, | |
| 38 WebUSBDevice::ControlTransferParameters* webParameters) | |
| 39 { | |
| 40 webParameters->direction = direction; | |
| 41 | 35 |
| 42 if (parameters.requestType() == "standard") | |
| 43 webParameters->type = WebUSBDevice::RequestType::Standard; | |
| 44 else if (parameters.requestType() == "class") | |
| 45 webParameters->type = WebUSBDevice::RequestType::Class; | |
| 46 else if (parameters.requestType() == "vendor") | |
| 47 webParameters->type = WebUSBDevice::RequestType::Vendor; | |
| 48 else | |
| 49 return DOMException::create(TypeMismatchError, "The control transfer req
uestType parameter is invalid."); | |
| 50 | |
| 51 // TODO(reillyg): Check for interface and endpoint availability if that is | |
| 52 // the control transfer target. | |
| 53 if (parameters.recipient() == "device") | |
| 54 webParameters->recipient = WebUSBDevice::RequestRecipient::Device; | |
| 55 else if (parameters.recipient() == "interface") | |
| 56 webParameters->recipient = WebUSBDevice::RequestRecipient::Interface; | |
| 57 else if (parameters.recipient() == "endpoint") | |
| 58 webParameters->recipient = WebUSBDevice::RequestRecipient::Endpoint; | |
| 59 else if (parameters.recipient() == "other") | |
| 60 webParameters->recipient = WebUSBDevice::RequestRecipient::Other; | |
| 61 else | |
| 62 return DOMException::create(TypeMismatchError, "The control transfer rec
ipient parameter is invalid."); | |
| 63 | |
| 64 webParameters->request = parameters.request(); | |
| 65 webParameters->value = parameters.value(); | |
| 66 webParameters->index = parameters.index(); | |
| 67 return nullptr; | |
| 68 } | |
| 69 | 36 |
| 70 String convertTransferStatus(const WebUSBTransferInfo::Status& status) | 37 String convertTransferStatus(const WebUSBTransferInfo::Status& status) |
| 71 { | 38 { |
| 72 switch (status) { | 39 switch (status) { |
| 73 case WebUSBTransferInfo::Status::Ok: | 40 case WebUSBTransferInfo::Status::Ok: |
| 74 return "ok"; | 41 return "ok"; |
| 75 case WebUSBTransferInfo::Status::Stall: | 42 case WebUSBTransferInfo::Status::Stall: |
| 76 return "stall"; | 43 return "stall"; |
| 77 case WebUSBTransferInfo::Status::Babble: | 44 case WebUSBTransferInfo::Status::Babble: |
| 78 return "babble"; | 45 return "babble"; |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 return USBDevice::create(device, resolver->getExecutionContext()); | 285 return USBDevice::create(device, resolver->getExecutionContext()); |
| 319 } | 286 } |
| 320 | 287 |
| 321 USBDevice::USBDevice(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context) | 288 USBDevice::USBDevice(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context) |
| 322 : ContextLifecycleObserver(context) | 289 : ContextLifecycleObserver(context) |
| 323 , PageLifecycleObserver(toDocument(context)->page()) | 290 , PageLifecycleObserver(toDocument(context)->page()) |
| 324 , m_device(device) | 291 , m_device(device) |
| 325 , m_opened(false) | 292 , m_opened(false) |
| 326 , m_deviceStateChangeInProgress(false) | 293 , m_deviceStateChangeInProgress(false) |
| 327 , m_configurationIndex(-1) | 294 , m_configurationIndex(-1) |
| 295 , m_inEndpoints(15) |
| 296 , m_outEndpoints(15) |
| 328 { | 297 { |
| 329 int configurationIndex = findConfigurationIndex(info().activeConfiguration); | 298 int configurationIndex = findConfigurationIndex(info().activeConfiguration); |
| 330 if (configurationIndex != -1) | 299 if (configurationIndex != -1) |
| 331 onConfigurationSelected(true /* success */, configurationIndex); | 300 onConfigurationSelected(true /* success */, configurationIndex); |
| 332 } | 301 } |
| 333 | 302 |
| 334 void USBDevice::onDeviceOpenedOrClosed(bool opened) | 303 void USBDevice::onDeviceOpenedOrClosed(bool opened) |
| 335 { | 304 { |
| 336 m_opened = opened; | 305 m_opened = opened; |
| 337 m_deviceStateChangeInProgress = false; | 306 m_deviceStateChangeInProgress = false; |
| 338 } | 307 } |
| 339 | 308 |
| 340 void USBDevice::onConfigurationSelected(bool success, size_t configurationIndex) | 309 void USBDevice::onConfigurationSelected(bool success, size_t configurationIndex) |
| 341 { | 310 { |
| 342 if (success) { | 311 if (success) { |
| 343 m_configurationIndex = configurationIndex; | 312 m_configurationIndex = configurationIndex; |
| 344 size_t numInterfaces = info().configurations[m_configurationIndex].inter
faces.size(); | 313 size_t numInterfaces = info().configurations[m_configurationIndex].inter
faces.size(); |
| 345 m_claimedInterfaces.clearAll(); | 314 m_claimedInterfaces.clearAll(); |
| 346 m_claimedInterfaces.resize(numInterfaces); | 315 m_claimedInterfaces.resize(numInterfaces); |
| 347 m_interfaceStateChangeInProgress.clearAll(); | 316 m_interfaceStateChangeInProgress.clearAll(); |
| 348 m_interfaceStateChangeInProgress.resize(numInterfaces); | 317 m_interfaceStateChangeInProgress.resize(numInterfaces); |
| 349 m_selectedAlternates.resize(numInterfaces); | 318 m_selectedAlternates.resize(numInterfaces); |
| 350 m_selectedAlternates.fill(0); | 319 m_selectedAlternates.fill(0); |
| 320 m_inEndpoints.clearAll(); |
| 321 m_outEndpoints.clearAll(); |
| 351 } | 322 } |
| 352 m_deviceStateChangeInProgress = false; | 323 m_deviceStateChangeInProgress = false; |
| 353 } | 324 } |
| 354 | 325 |
| 355 void USBDevice::onInterfaceClaimedOrUnclaimed(bool claimed, size_t interfaceInde
x) | 326 void USBDevice::onInterfaceClaimedOrUnclaimed(bool claimed, size_t interfaceInde
x) |
| 356 { | 327 { |
| 357 if (claimed) | 328 if (claimed) { |
| 358 m_claimedInterfaces.set(interfaceIndex); | 329 m_claimedInterfaces.set(interfaceIndex); |
| 359 else | 330 } else { |
| 360 m_claimedInterfaces.clear(interfaceIndex); | 331 m_claimedInterfaces.clear(interfaceIndex); |
| 332 m_selectedAlternates[interfaceIndex] = 0; |
| 333 } |
| 334 setEndpointsForInterface(interfaceIndex, claimed); |
| 361 m_interfaceStateChangeInProgress.clear(interfaceIndex); | 335 m_interfaceStateChangeInProgress.clear(interfaceIndex); |
| 362 } | 336 } |
| 363 | 337 |
| 364 void USBDevice::onAlternateInterfaceSelected(bool success, size_t interfaceIndex
, size_t alternateIndex) | 338 void USBDevice::onAlternateInterfaceSelected(bool success, size_t interfaceIndex
, size_t alternateIndex) |
| 365 { | 339 { |
| 366 if (success) | 340 if (success) |
| 367 m_selectedAlternates[interfaceIndex] = alternateIndex; | 341 m_selectedAlternates[interfaceIndex] = alternateIndex; |
| 342 setEndpointsForInterface(interfaceIndex, success); |
| 368 m_interfaceStateChangeInProgress.clear(interfaceIndex); | 343 m_interfaceStateChangeInProgress.clear(interfaceIndex); |
| 369 } | 344 } |
| 370 | 345 |
| 371 bool USBDevice::isInterfaceClaimed(size_t configurationIndex, size_t interfaceIn
dex) const | 346 bool USBDevice::isInterfaceClaimed(size_t configurationIndex, size_t interfaceIn
dex) const |
| 372 { | 347 { |
| 373 return m_configurationIndex != -1 && static_cast<size_t>(m_configurationInde
x) == configurationIndex && m_claimedInterfaces.get(interfaceIndex); | 348 return m_configurationIndex != -1 && static_cast<size_t>(m_configurationInde
x) == configurationIndex && m_claimedInterfaces.get(interfaceIndex); |
| 374 } | 349 } |
| 375 | 350 |
| 376 size_t USBDevice::selectedAlternateInterface(size_t interfaceIndex) const | 351 size_t USBDevice::selectedAlternateInterface(size_t interfaceIndex) const |
| 377 { | 352 { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 ScriptPromise promise = resolver->promise(); | 447 ScriptPromise promise = resolver->promise(); |
| 473 if (ensureDeviceConfigured(resolver)) { | 448 if (ensureDeviceConfigured(resolver)) { |
| 474 int interfaceIndex = findInterfaceIndex(interfaceNumber); | 449 int interfaceIndex = findInterfaceIndex(interfaceNumber); |
| 475 if (interfaceIndex == -1) { | 450 if (interfaceIndex == -1) { |
| 476 resolver->reject(DOMException::create(NotFoundError, "The interface
number provided is not supported by the device in its current configuration.")); | 451 resolver->reject(DOMException::create(NotFoundError, "The interface
number provided is not supported by the device in its current configuration.")); |
| 477 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) { | 452 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) { |
| 478 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS
tateChangeInProgress)); | 453 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS
tateChangeInProgress)); |
| 479 } else if (!m_claimedInterfaces.get(interfaceIndex)) { | 454 } else if (!m_claimedInterfaces.get(interfaceIndex)) { |
| 480 resolver->resolve(); | 455 resolver->resolve(); |
| 481 } else { | 456 } else { |
| 457 // Mark this interface's endpoints unavailable while its state is |
| 458 // changing. |
| 459 setEndpointsForInterface(interfaceIndex, false); |
| 482 m_interfaceStateChangeInProgress.set(interfaceIndex); | 460 m_interfaceStateChangeInProgress.set(interfaceIndex); |
| 483 m_device->releaseInterface(interfaceNumber, new ClaimInterfacePromis
eAdapter(this, resolver, interfaceIndex, false /* release */)); | 461 m_device->releaseInterface(interfaceNumber, new ClaimInterfacePromis
eAdapter(this, resolver, interfaceIndex, false /* release */)); |
| 484 } | 462 } |
| 485 } | 463 } |
| 486 return promise; | 464 return promise; |
| 487 } | 465 } |
| 488 | 466 |
| 489 ScriptPromise USBDevice::selectAlternateInterface(ScriptState* scriptState, uint
8_t interfaceNumber, uint8_t alternateSetting) | 467 ScriptPromise USBDevice::selectAlternateInterface(ScriptState* scriptState, uint
8_t interfaceNumber, uint8_t alternateSetting) |
| 490 { | 468 { |
| 491 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 469 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
| 492 ScriptPromise promise = resolver->promise(); | 470 ScriptPromise promise = resolver->promise(); |
| 493 if (ensureInterfaceClaimed(interfaceNumber, resolver)) { | 471 if (ensureInterfaceClaimed(interfaceNumber, resolver)) { |
| 494 // TODO(reillyg): This is duplicated work. | 472 // TODO(reillyg): This is duplicated work. |
| 495 int interfaceIndex = findInterfaceIndex(interfaceNumber); | 473 int interfaceIndex = findInterfaceIndex(interfaceNumber); |
| 496 ASSERT(interfaceIndex != -1); | 474 ASSERT(interfaceIndex != -1); |
| 497 int alternateIndex = findAlternateIndex(interfaceIndex, alternateSetting
); | 475 int alternateIndex = findAlternateIndex(interfaceIndex, alternateSetting
); |
| 498 if (alternateIndex == -1) { | 476 if (alternateIndex == -1) { |
| 499 resolver->reject(DOMException::create(NotFoundError, "The alternate
setting provided is not supported by the device in its current configuration."))
; | 477 resolver->reject(DOMException::create(NotFoundError, "The alternate
setting provided is not supported by the device in its current configuration."))
; |
| 500 } else { | 478 } else { |
| 479 // Mark this old alternate interface's endpoints unavailable while |
| 480 // the change is in progress. |
| 481 setEndpointsForInterface(interfaceIndex, false); |
| 501 m_interfaceStateChangeInProgress.set(interfaceIndex); | 482 m_interfaceStateChangeInProgress.set(interfaceIndex); |
| 502 m_device->setInterface(interfaceNumber, alternateSetting, new Select
AlternateInterfacePromiseAdapter(this, resolver, interfaceIndex, alternateIndex)
); | 483 m_device->setInterface(interfaceNumber, alternateSetting, new Select
AlternateInterfacePromiseAdapter(this, resolver, interfaceIndex, alternateIndex)
); |
| 503 } | 484 } |
| 504 } | 485 } |
| 505 return promise; | 486 return promise; |
| 506 } | 487 } |
| 507 | 488 |
| 508 ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo
ntrolTransferParameters& setup, unsigned length) | 489 ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo
ntrolTransferParameters& setup, unsigned length) |
| 509 { | 490 { |
| 510 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 491 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
| 511 ScriptPromise promise = resolver->promise(); | 492 ScriptPromise promise = resolver->promise(); |
| 512 if (ensureDeviceConfigured(resolver)) { | 493 if (ensureDeviceConfigured(resolver)) { |
| 513 WebUSBDevice::ControlTransferParameters parameters; | 494 WebUSBDevice::ControlTransferParameters parameters; |
| 514 DOMException* error = convertControlTransferParameters(WebUSBDevice::Tra
nsferDirection::In, setup, ¶meters); | 495 if (convertControlTransferParameters(WebUSBDevice::TransferDirection::In
, setup, ¶meters, resolver)) |
| 515 if (error) | |
| 516 resolver->reject(error); | |
| 517 else | |
| 518 m_device->controlTransfer(parameters, nullptr, length, 0, new Callba
ckPromiseAdapter<InputTransferResult, USBError>(resolver)); | 496 m_device->controlTransfer(parameters, nullptr, length, 0, new Callba
ckPromiseAdapter<InputTransferResult, USBError>(resolver)); |
| 519 } | 497 } |
| 520 return promise; | 498 return promise; |
| 521 } | 499 } |
| 522 | 500 |
| 523 ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC
ontrolTransferParameters& setup) | 501 ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC
ontrolTransferParameters& setup) |
| 524 { | 502 { |
| 525 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 503 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
| 526 ScriptPromise promise = resolver->promise(); | 504 ScriptPromise promise = resolver->promise(); |
| 527 if (ensureDeviceConfigured(resolver)) { | 505 if (ensureDeviceConfigured(resolver)) { |
| 528 WebUSBDevice::ControlTransferParameters parameters; | 506 WebUSBDevice::ControlTransferParameters parameters; |
| 529 DOMException* error = convertControlTransferParameters(WebUSBDevice::Tra
nsferDirection::Out, setup, ¶meters); | 507 if (convertControlTransferParameters(WebUSBDevice::TransferDirection::Ou
t, setup, ¶meters, resolver)) |
| 530 if (error) | |
| 531 resolver->reject(error); | |
| 532 else | |
| 533 m_device->controlTransfer(parameters, nullptr, 0, 0, new CallbackPro
miseAdapter<OutputTransferResult, USBError>(resolver)); | 508 m_device->controlTransfer(parameters, nullptr, 0, 0, new CallbackPro
miseAdapter<OutputTransferResult, USBError>(resolver)); |
| 534 } | 509 } |
| 535 return promise; | 510 return promise; |
| 536 } | 511 } |
| 537 | 512 |
| 538 ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC
ontrolTransferParameters& setup, const ArrayBufferOrArrayBufferView& data) | 513 ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC
ontrolTransferParameters& setup, const ArrayBufferOrArrayBufferView& data) |
| 539 { | 514 { |
| 540 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 515 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
| 541 ScriptPromise promise = resolver->promise(); | 516 ScriptPromise promise = resolver->promise(); |
| 542 if (ensureDeviceConfigured(resolver)) { | 517 if (ensureDeviceConfigured(resolver)) { |
| 543 WebUSBDevice::ControlTransferParameters parameters; | 518 WebUSBDevice::ControlTransferParameters parameters; |
| 544 DOMException* error = convertControlTransferParameters(WebUSBDevice::Tra
nsferDirection::Out, setup, ¶meters); | 519 if (convertControlTransferParameters(WebUSBDevice::TransferDirection::Ou
t, setup, ¶meters, resolver)) { |
| 545 if (error) { | |
| 546 resolver->reject(error); | |
| 547 } else { | |
| 548 BufferSource buffer(data); | 520 BufferSource buffer(data); |
| 549 m_device->controlTransfer(parameters, buffer.data(), buffer.size(),
0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver)); | 521 m_device->controlTransfer(parameters, buffer.data(), buffer.size(),
0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver)); |
| 550 } | 522 } |
| 551 } | 523 } |
| 552 return promise; | 524 return promise; |
| 553 } | 525 } |
| 554 | 526 |
| 555 ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, String direction, u
int8_t endpointNumber) | 527 ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, String direction, u
int8_t endpointNumber) |
| 556 { | 528 { |
| 557 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 529 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState
ChangeInProgress)); | 688 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState
ChangeInProgress)); |
| 717 else if (!m_claimedInterfaces.get(interfaceIndex)) | 689 else if (!m_claimedInterfaces.get(interfaceIndex)) |
| 718 resolver->reject(DOMException::create(InvalidStateError, "The specified
interface has not been claimed.")); | 690 resolver->reject(DOMException::create(InvalidStateError, "The specified
interface has not been claimed.")); |
| 719 else | 691 else |
| 720 return true; | 692 return true; |
| 721 return false; | 693 return false; |
| 722 } | 694 } |
| 723 | 695 |
| 724 bool USBDevice::ensureEndpointAvailable(bool inTransfer, uint8_t endpointNumber,
ScriptPromiseResolver* resolver) const | 696 bool USBDevice::ensureEndpointAvailable(bool inTransfer, uint8_t endpointNumber,
ScriptPromiseResolver* resolver) const |
| 725 { | 697 { |
| 726 // TODO(reillyg): Check endpoint availability once Blink is tracking which | 698 if (!ensureDeviceConfigured(resolver)) |
| 727 // alternate interfaces are selected. | 699 return false; |
| 728 return ensureDeviceConfigured(resolver); | 700 if (endpointNumber == 0 || endpointNumber >= 16) { |
| 701 resolver->reject(DOMException::create(IndexSizeError, "The specified end
point number is out of range.")); |
| 702 return false; |
| 703 } |
| 704 auto& bitVector = inTransfer ? m_inEndpoints : m_outEndpoints; |
| 705 if (!bitVector.get(endpointNumber - 1)) { |
| 706 resolver->reject(DOMException::create(NotFoundError, "The specified endp
oint is not part of a claimed and selected alternate interface.")); |
| 707 return false; |
| 708 } |
| 709 return true; |
| 729 } | 710 } |
| 730 | 711 |
| 731 bool USBDevice::anyInterfaceChangeInProgress() const | 712 bool USBDevice::anyInterfaceChangeInProgress() const |
| 732 { | 713 { |
| 733 for (size_t i = 0; i < m_interfaceStateChangeInProgress.size(); ++i) { | 714 for (size_t i = 0; i < m_interfaceStateChangeInProgress.size(); ++i) { |
| 734 if (m_interfaceStateChangeInProgress.quickGet(i)) | 715 if (m_interfaceStateChangeInProgress.quickGet(i)) |
| 735 return true; | 716 return true; |
| 736 } | 717 } |
| 737 return false; | 718 return false; |
| 738 } | 719 } |
| 739 | 720 |
| 721 bool USBDevice::convertControlTransferParameters( |
| 722 WebUSBDevice::TransferDirection direction, |
| 723 const USBControlTransferParameters& parameters, |
| 724 WebUSBDevice::ControlTransferParameters* webParameters, |
| 725 ScriptPromiseResolver* resolver) const |
| 726 { |
| 727 webParameters->direction = direction; |
| 728 |
| 729 if (parameters.requestType() == "standard") { |
| 730 webParameters->type = WebUSBDevice::RequestType::Standard; |
| 731 } else if (parameters.requestType() == "class") { |
| 732 webParameters->type = WebUSBDevice::RequestType::Class; |
| 733 } else if (parameters.requestType() == "vendor") { |
| 734 webParameters->type = WebUSBDevice::RequestType::Vendor; |
| 735 } else { |
| 736 resolver->reject(DOMException::create(TypeMismatchError, "The control tr
ansfer requestType parameter is invalid.")); |
| 737 return false; |
| 738 } |
| 739 |
| 740 if (parameters.recipient() == "device") { |
| 741 webParameters->recipient = WebUSBDevice::RequestRecipient::Device; |
| 742 } else if (parameters.recipient() == "interface") { |
| 743 size_t interfaceNumber = parameters.index() & 0xff; |
| 744 if (!ensureInterfaceClaimed(interfaceNumber, resolver)) |
| 745 return false; |
| 746 webParameters->recipient = WebUSBDevice::RequestRecipient::Interface; |
| 747 } else if (parameters.recipient() == "endpoint") { |
| 748 bool inTransfer = parameters.index() & 0x80; |
| 749 size_t endpointNumber = parameters.index() & 0x0f; |
| 750 if (!ensureEndpointAvailable(inTransfer, endpointNumber, resolver)) |
| 751 return false; |
| 752 webParameters->recipient = WebUSBDevice::RequestRecipient::Endpoint; |
| 753 } else if (parameters.recipient() == "other") { |
| 754 webParameters->recipient = WebUSBDevice::RequestRecipient::Other; |
| 755 } else { |
| 756 resolver->reject(DOMException::create(TypeMismatchError, "The control tr
ansfer recipient parameter is invalid.")); |
| 757 return false; |
| 758 } |
| 759 |
| 760 webParameters->request = parameters.request(); |
| 761 webParameters->value = parameters.value(); |
| 762 webParameters->index = parameters.index(); |
| 763 return true; |
| 764 } |
| 765 |
| 766 void USBDevice::setEndpointsForInterface(size_t interfaceIndex, bool set) |
| 767 { |
| 768 const auto& configuration = info().configurations[m_configurationIndex]; |
| 769 const auto& interface = configuration.interfaces[interfaceIndex]; |
| 770 const auto& alternate = interface.alternates[m_selectedAlternates[interfaceI
ndex]]; |
| 771 for (const auto& endpoint : alternate.endpoints) { |
| 772 if (endpoint.endpointNumber == 0 || endpoint.endpointNumber >= 16) |
| 773 continue; // Ignore endpoints with invalid indices. |
| 774 auto& bitVector = endpoint.direction == WebUSBDevice::TransferDirection:
:In ? m_inEndpoints : m_outEndpoints; |
| 775 if (set) |
| 776 bitVector.set(endpoint.endpointNumber - 1); |
| 777 else |
| 778 bitVector.clear(endpoint.endpointNumber - 1); |
| 779 } |
| 780 } |
| 781 |
| 740 } // namespace blink | 782 } // namespace blink |
| OLD | NEW |