| 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" |
| 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/Document.h" | |
| 15 #include "core/dom/ExceptionCode.h" | 14 #include "core/dom/ExceptionCode.h" |
| 16 #include "modules/webusb/USBConfiguration.h" | 15 #include "modules/webusb/USBConfiguration.h" |
| 17 #include "modules/webusb/USBControlTransferParameters.h" | 16 #include "modules/webusb/USBControlTransferParameters.h" |
| 18 #include "modules/webusb/USBError.h" | 17 #include "modules/webusb/USBError.h" |
| 19 #include "modules/webusb/USBInTransferResult.h" | 18 #include "modules/webusb/USBInTransferResult.h" |
| 20 #include "modules/webusb/USBIsochronousInTransferResult.h" | 19 #include "modules/webusb/USBIsochronousInTransferResult.h" |
| 21 #include "modules/webusb/USBIsochronousOutTransferResult.h" | 20 #include "modules/webusb/USBIsochronousOutTransferResult.h" |
| 22 #include "modules/webusb/USBOutTransferResult.h" | 21 #include "modules/webusb/USBOutTransferResult.h" |
| 23 #include "public/platform/modules/webusb/WebUSBTransferInfo.h" | 22 #include "public/platform/modules/webusb/WebUSBTransferInfo.h" |
| 24 #include "wtf/Assertions.h" | 23 #include "wtf/Assertions.h" |
| 25 | 24 |
| 26 namespace blink { | 25 namespace blink { |
| 27 | 26 |
| 28 namespace { | 27 namespace { |
| 29 | 28 |
| 30 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."; |
| 31 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."; |
| 32 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."; |
| 33 const char kOpenRequired[] = "The device must be opened first."; | 32 const char kOpenRequired[] = "The device must be opened first."; |
| 34 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."; | |
| 35 | |
| 36 | |
| 37 | 33 |
| 38 String convertTransferStatus(const WebUSBTransferInfo::Status& status) | 34 String convertTransferStatus(const WebUSBTransferInfo::Status& status) |
| 39 { | 35 { |
| 40 switch (status) { | 36 switch (status) { |
| 41 case WebUSBTransferInfo::Status::Ok: | 37 case WebUSBTransferInfo::Status::Ok: |
| 42 return "ok"; | 38 return "ok"; |
| 43 case WebUSBTransferInfo::Status::Stall: | 39 case WebUSBTransferInfo::Status::Stall: |
| 44 return "stall"; | 40 return "stall"; |
| 45 case WebUSBTransferInfo::Status::Babble: | 41 case WebUSBTransferInfo::Status::Babble: |
| 46 return "babble"; | 42 return "babble"; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 58 , m_desiredState(desiredState) | 54 , m_desiredState(desiredState) |
| 59 { | 55 { |
| 60 } | 56 } |
| 61 | 57 |
| 62 void onSuccess() override | 58 void onSuccess() override |
| 63 { | 59 { |
| 64 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 60 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
| 65 return; | 61 return; |
| 66 | 62 |
| 67 m_device->onDeviceOpenedOrClosed(m_desiredState); | 63 m_device->onDeviceOpenedOrClosed(m_desiredState); |
| 68 if (m_device->page()->isPageVisible()) { | 64 m_resolver->resolve(); |
| 69 m_resolver->resolve(); | |
| 70 } else { | |
| 71 m_device->pageVisibilityChanged(); | |
| 72 m_resolver->reject(DOMException::create(SecurityError, kVisibiltyErr
or)); | |
| 73 return; | |
| 74 } | |
| 75 } | 65 } |
| 76 | 66 |
| 77 void onError(const WebUSBError& e) override | 67 void onError(const WebUSBError& e) override |
| 78 { | 68 { |
| 79 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 69 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
| 80 return; | 70 return; |
| 81 m_device->onDeviceOpenedOrClosed(!m_desiredState); | 71 m_device->onDeviceOpenedOrClosed(!m_desiredState); |
| 82 m_resolver->reject(USBError::take(m_resolver, e)); | 72 m_resolver->reject(USBError::take(m_resolver, e)); |
| 83 } | 73 } |
| 84 | 74 |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 } // namespace | 271 } // namespace |
| 282 | 272 |
| 283 // static | 273 // static |
| 284 USBDevice* USBDevice::take(ScriptPromiseResolver* resolver, PassOwnPtr<WebUSBDev
ice> device) | 274 USBDevice* USBDevice::take(ScriptPromiseResolver* resolver, PassOwnPtr<WebUSBDev
ice> device) |
| 285 { | 275 { |
| 286 return USBDevice::create(device, resolver->getExecutionContext()); | 276 return USBDevice::create(device, resolver->getExecutionContext()); |
| 287 } | 277 } |
| 288 | 278 |
| 289 USBDevice::USBDevice(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context) | 279 USBDevice::USBDevice(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context) |
| 290 : ContextLifecycleObserver(context) | 280 : ContextLifecycleObserver(context) |
| 291 , PageLifecycleObserver(toDocument(context)->page()) | |
| 292 , m_device(device) | 281 , m_device(device) |
| 293 , m_opened(false) | 282 , m_opened(false) |
| 294 , m_deviceStateChangeInProgress(false) | 283 , m_deviceStateChangeInProgress(false) |
| 295 , m_configurationIndex(-1) | 284 , m_configurationIndex(-1) |
| 296 , m_inEndpoints(15) | 285 , m_inEndpoints(15) |
| 297 , m_outEndpoints(15) | 286 , m_outEndpoints(15) |
| 298 { | 287 { |
| 299 int configurationIndex = findConfigurationIndex(info().activeConfiguration); | 288 int configurationIndex = findConfigurationIndex(info().activeConfiguration); |
| 300 if (configurationIndex != -1) | 289 if (configurationIndex != -1) |
| 301 onConfigurationSelected(true /* success */, configurationIndex); | 290 onConfigurationSelected(true /* success */, configurationIndex); |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 } | 577 } |
| 589 | 578 |
| 590 void USBDevice::contextDestroyed() | 579 void USBDevice::contextDestroyed() |
| 591 { | 580 { |
| 592 if (m_opened) { | 581 if (m_opened) { |
| 593 m_device->close(new WebUSBDeviceCloseCallbacks()); | 582 m_device->close(new WebUSBDeviceCloseCallbacks()); |
| 594 m_opened = false; | 583 m_opened = false; |
| 595 } | 584 } |
| 596 } | 585 } |
| 597 | 586 |
| 598 void USBDevice::pageVisibilityChanged() | |
| 599 { | |
| 600 if (!page()->isPageVisible() && m_opened) { | |
| 601 m_device->close(new WebUSBDeviceCloseCallbacks()); | |
| 602 m_opened = false; | |
| 603 } | |
| 604 } | |
| 605 | |
| 606 DEFINE_TRACE(USBDevice) | 587 DEFINE_TRACE(USBDevice) |
| 607 { | 588 { |
| 608 ContextLifecycleObserver::trace(visitor); | 589 ContextLifecycleObserver::trace(visitor); |
| 609 PageLifecycleObserver::trace(visitor); | |
| 610 } | 590 } |
| 611 | 591 |
| 612 int USBDevice::findConfigurationIndex(uint8_t configurationValue) const | 592 int USBDevice::findConfigurationIndex(uint8_t configurationValue) const |
| 613 { | 593 { |
| 614 const auto& configurations = info().configurations; | 594 const auto& configurations = info().configurations; |
| 615 for (size_t i = 0; i < configurations.size(); ++i) { | 595 for (size_t i = 0; i < configurations.size(); ++i) { |
| 616 if (configurations[i].configurationValue == configurationValue) | 596 if (configurations[i].configurationValue == configurationValue) |
| 617 return i; | 597 return i; |
| 618 } | 598 } |
| 619 return -1; | 599 return -1; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 634 { | 614 { |
| 635 ASSERT(m_configurationIndex != -1); | 615 ASSERT(m_configurationIndex != -1); |
| 636 const auto& alternates = info().configurations[m_configurationIndex].interfa
ces[interfaceIndex].alternates; | 616 const auto& alternates = info().configurations[m_configurationIndex].interfa
ces[interfaceIndex].alternates; |
| 637 for (size_t i = 0; i < alternates.size(); ++i) { | 617 for (size_t i = 0; i < alternates.size(); ++i) { |
| 638 if (alternates[i].alternateSetting == alternateSetting) | 618 if (alternates[i].alternateSetting == alternateSetting) |
| 639 return i; | 619 return i; |
| 640 } | 620 } |
| 641 return -1; | 621 return -1; |
| 642 } | 622 } |
| 643 | 623 |
| 644 bool USBDevice::ensurePageVisible(ScriptPromiseResolver* resolver) const | |
| 645 { | |
| 646 if (!page()->isPageVisible()) { | |
| 647 resolver->reject(DOMException::create(SecurityError, kVisibiltyError)); | |
| 648 return false; | |
| 649 } | |
| 650 return true; | |
| 651 } | |
| 652 | |
| 653 bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver*
resolver) const | 624 bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver*
resolver) const |
| 654 { | 625 { |
| 655 if (!ensurePageVisible(resolver)) | |
| 656 return false; | |
| 657 if (m_deviceStateChangeInProgress) | 626 if (m_deviceStateChangeInProgress) |
| 658 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha
ngeInProgress)); | 627 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha
ngeInProgress)); |
| 659 else if (anyInterfaceChangeInProgress()) | 628 else if (anyInterfaceChangeInProgress()) |
| 660 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState
ChangeInProgress)); | 629 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState
ChangeInProgress)); |
| 661 else | 630 else |
| 662 return true; | 631 return true; |
| 663 return false; | 632 return false; |
| 664 } | 633 } |
| 665 | 634 |
| 666 bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const | 635 bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const |
| 667 { | 636 { |
| 668 if (!ensurePageVisible(resolver)) | |
| 669 return false; | |
| 670 if (m_deviceStateChangeInProgress) | 637 if (m_deviceStateChangeInProgress) |
| 671 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha
ngeInProgress)); | 638 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha
ngeInProgress)); |
| 672 else if (!m_opened) | 639 else if (!m_opened) |
| 673 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired))
; | 640 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired))
; |
| 674 else if (m_configurationIndex == -1) | 641 else if (m_configurationIndex == -1) |
| 675 resolver->reject(DOMException::create(InvalidStateError, "The device mus
t have a configuration selected.")); | 642 resolver->reject(DOMException::create(InvalidStateError, "The device mus
t have a configuration selected.")); |
| 676 else | 643 else |
| 677 return true; | 644 return true; |
| 678 return false; | 645 return false; |
| 679 } | 646 } |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 continue; // Ignore endpoints with invalid indices. | 741 continue; // Ignore endpoints with invalid indices. |
| 775 auto& bitVector = endpoint.direction == WebUSBDevice::TransferDirection:
:In ? m_inEndpoints : m_outEndpoints; | 742 auto& bitVector = endpoint.direction == WebUSBDevice::TransferDirection:
:In ? m_inEndpoints : m_outEndpoints; |
| 776 if (set) | 743 if (set) |
| 777 bitVector.set(endpoint.endpointNumber - 1); | 744 bitVector.set(endpoint.endpointNumber - 1); |
| 778 else | 745 else |
| 779 bitVector.clear(endpoint.endpointNumber - 1); | 746 bitVector.clear(endpoint.endpointNumber - 1); |
| 780 } | 747 } |
| 781 } | 748 } |
| 782 | 749 |
| 783 } // namespace blink | 750 } // namespace blink |
| OLD | NEW |