Chromium Code Reviews| 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 12 matching lines...) Expand all Loading... | |
| 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."; | 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 | 34 |
| 34 DOMException* convertControlTransferParameters( | 35 DOMException* convertControlTransferParameters( |
| 35 WebUSBDevice::TransferDirection direction, | 36 WebUSBDevice::TransferDirection direction, |
| 36 const USBControlTransferParameters& parameters, | 37 const USBControlTransferParameters& parameters, |
| 37 WebUSBDevice::ControlTransferParameters* webParameters) | 38 WebUSBDevice::ControlTransferParameters* webParameters) |
| 38 { | 39 { |
| 39 webParameters->direction = direction; | 40 webParameters->direction = direction; |
| 40 | 41 |
| 41 if (parameters.requestType() == "standard") | 42 if (parameters.requestType() == "standard") |
| 42 webParameters->type = WebUSBDevice::RequestType::Standard; | 43 webParameters->type = WebUSBDevice::RequestType::Standard; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 87 : m_device(device) | 88 : m_device(device) |
| 88 , m_resolver(resolver) | 89 , m_resolver(resolver) |
| 89 , m_desiredState(desiredState) | 90 , m_desiredState(desiredState) |
| 90 { | 91 { |
| 91 } | 92 } |
| 92 | 93 |
| 93 void onSuccess() override | 94 void onSuccess() override |
| 94 { | 95 { |
| 95 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) | 96 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) |
| 96 return; | 97 return; |
| 98 | |
| 97 m_device->onDeviceOpenedOrClosed(m_desiredState); | 99 m_device->onDeviceOpenedOrClosed(m_desiredState); |
| 98 m_resolver->resolve(); | 100 if (m_device->page()->isPageVisible()) { |
| 101 m_resolver->resolve(); | |
| 102 } else { | |
| 103 m_device->pageVisibilityChanged(); | |
| 104 m_resolver->reject(DOMException::create(SecurityError, kVisibiltyErr or)); | |
| 105 return; | |
| 106 } | |
| 99 } | 107 } |
| 100 | 108 |
| 101 void onError(const WebUSBError& e) override | 109 void onError(const WebUSBError& e) override |
| 102 { | 110 { |
| 103 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) | 111 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) |
| 104 return; | 112 return; |
| 105 m_device->onDeviceOpenedOrClosed(!m_desiredState); | 113 m_device->onDeviceOpenedOrClosed(!m_desiredState); |
| 106 m_resolver->reject(USBError::take(m_resolver, e)); | 114 m_resolver->reject(USBError::take(m_resolver, e)); |
| 107 } | 115 } |
| 108 | 116 |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 305 } // namespace | 313 } // namespace |
| 306 | 314 |
| 307 // static | 315 // static |
| 308 USBDevice* USBDevice::take(ScriptPromiseResolver* resolver, PassOwnPtr<WebUSBDev ice> device) | 316 USBDevice* USBDevice::take(ScriptPromiseResolver* resolver, PassOwnPtr<WebUSBDev ice> device) |
| 309 { | 317 { |
| 310 return USBDevice::create(device, resolver->getExecutionContext()); | 318 return USBDevice::create(device, resolver->getExecutionContext()); |
| 311 } | 319 } |
| 312 | 320 |
| 313 USBDevice::USBDevice(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context) | 321 USBDevice::USBDevice(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context) |
| 314 : ContextLifecycleObserver(context) | 322 : ContextLifecycleObserver(context) |
| 323 , PageLifecycleObserver(toDocument(context)->page()) | |
| 315 , m_device(device) | 324 , m_device(device) |
| 316 , m_opened(false) | 325 , m_opened(false) |
| 317 , m_deviceStateChangeInProgress(false) | 326 , m_deviceStateChangeInProgress(false) |
| 318 , m_configurationIndex(-1) | 327 , m_configurationIndex(-1) |
| 319 { | 328 { |
| 320 int configurationIndex = findConfigurationIndex(info().activeConfiguration); | 329 int configurationIndex = findConfigurationIndex(info().activeConfiguration); |
| 321 if (configurationIndex != -1) | 330 if (configurationIndex != -1) |
| 322 onConfigurationSelected(true /* success */, configurationIndex); | 331 onConfigurationSelected(true /* success */, configurationIndex); |
| 323 } | 332 } |
| 324 | 333 |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 600 if (!m_opened) | 609 if (!m_opened) |
| 601 resolver->reject(DOMException::create(InvalidStateError, kOpenRequir ed)); | 610 resolver->reject(DOMException::create(InvalidStateError, kOpenRequir ed)); |
| 602 else | 611 else |
| 603 m_device->reset(new CallbackPromiseAdapter<void, USBError>(resolver) ); | 612 m_device->reset(new CallbackPromiseAdapter<void, USBError>(resolver) ); |
| 604 } | 613 } |
| 605 return promise; | 614 return promise; |
| 606 } | 615 } |
| 607 | 616 |
| 608 void USBDevice::contextDestroyed() | 617 void USBDevice::contextDestroyed() |
| 609 { | 618 { |
| 610 if (m_opened) | 619 if (m_opened) { |
| 611 m_device->close(new WebUSBDeviceCloseCallbacks()); | 620 m_device->close(new WebUSBDeviceCloseCallbacks()); |
| 621 m_opened = false; | |
| 622 } | |
| 623 } | |
| 624 | |
| 625 void USBDevice::pageVisibilityChanged() | |
| 626 { | |
| 627 if (!page()->isPageVisible() && m_opened) { | |
| 628 m_device->close(new WebUSBDeviceCloseCallbacks()); | |
| 629 m_opened = false; | |
| 630 } | |
| 612 } | 631 } |
| 613 | 632 |
| 614 DEFINE_TRACE(USBDevice) | 633 DEFINE_TRACE(USBDevice) |
| 615 { | 634 { |
| 616 ContextLifecycleObserver::trace(visitor); | 635 ContextLifecycleObserver::trace(visitor); |
| 636 PageLifecycleObserver::trace(visitor); | |
| 617 } | 637 } |
| 618 | 638 |
| 619 int USBDevice::findConfigurationIndex(uint8_t configurationValue) const | 639 int USBDevice::findConfigurationIndex(uint8_t configurationValue) const |
| 620 { | 640 { |
| 621 const auto& configurations = info().configurations; | 641 const auto& configurations = info().configurations; |
| 622 for (size_t i = 0; i < configurations.size(); ++i) { | 642 for (size_t i = 0; i < configurations.size(); ++i) { |
| 623 if (configurations[i].configurationValue == configurationValue) | 643 if (configurations[i].configurationValue == configurationValue) |
| 624 return i; | 644 return i; |
| 625 } | 645 } |
| 626 return -1; | 646 return -1; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 641 { | 661 { |
| 642 ASSERT(m_configurationIndex != -1); | 662 ASSERT(m_configurationIndex != -1); |
| 643 const auto& alternates = info().configurations[m_configurationIndex].interfa ces[interfaceIndex].alternates; | 663 const auto& alternates = info().configurations[m_configurationIndex].interfa ces[interfaceIndex].alternates; |
| 644 for (size_t i = 0; i < alternates.size(); ++i) { | 664 for (size_t i = 0; i < alternates.size(); ++i) { |
| 645 if (alternates[i].alternateSetting == alternateSetting) | 665 if (alternates[i].alternateSetting == alternateSetting) |
| 646 return i; | 666 return i; |
| 647 } | 667 } |
| 648 return -1; | 668 return -1; |
| 649 } | 669 } |
| 650 | 670 |
| 671 bool USBDevice::ensurePageVisible(ScriptPromiseResolver* resolver) const | |
| 672 { | |
| 673 if (!page()->isPageVisible()) { | |
| 674 resolver->reject(DOMException::create(SecurityError, kVisibiltyError)); | |
| 675 return false; | |
| 676 } | |
| 677 return true; | |
| 678 } | |
| 679 | |
| 651 bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver* resolver) const | 680 bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver* resolver) const |
| 652 { | 681 { |
| 653 if (m_deviceStateChangeInProgress) { | 682 if (ensurePageVisible(resolver)) { |
|
ortuno
2016/03/22 02:09:08
nit: if you want to save a level of indentation:
i
| |
| 654 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); | 683 if (m_deviceStateChangeInProgress) |
| 655 } else if (anyInterfaceChangeInProgress()) { | 684 resolver->reject(DOMException::create(InvalidStateError, kDeviceStat eChangeInProgress)); |
| 656 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress)); | 685 else if (anyInterfaceChangeInProgress()) |
| 657 } else { | 686 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS tateChangeInProgress)); |
| 658 return true; | 687 else |
| 688 return true; | |
| 659 } | 689 } |
| 660 return false; | 690 return false; |
| 661 } | 691 } |
| 662 | 692 |
| 663 bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const | 693 bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const |
| 664 { | 694 { |
| 665 if (!m_opened) { | 695 if (ensurePageVisible(resolver)) { |
|
ortuno
2016/03/22 02:09:08
nit: same here
| |
| 666 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ; | 696 if (m_deviceStateChangeInProgress) |
| 667 } else if (m_deviceStateChangeInProgress) { | 697 resolver->reject(DOMException::create(InvalidStateError, kDeviceStat eChangeInProgress)); |
| 668 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); | 698 else if (!m_opened) |
| 669 } else if (m_configurationIndex == -1) { | 699 resolver->reject(DOMException::create(InvalidStateError, kOpenRequir ed)); |
| 670 resolver->reject(DOMException::create(InvalidStateError, "The device mus t have a configuration selected.")); | 700 else if (m_configurationIndex == -1) |
| 671 } else { | 701 resolver->reject(DOMException::create(InvalidStateError, "The device must have a configuration selected.")); |
| 672 return true; | 702 else |
| 703 return true; | |
| 673 } | 704 } |
| 674 return false; | 705 return false; |
| 675 } | 706 } |
| 676 | 707 |
| 677 bool USBDevice::ensureInterfaceClaimed(uint8_t interfaceNumber, ScriptPromiseRes olver* resolver) const | 708 bool USBDevice::ensureInterfaceClaimed(uint8_t interfaceNumber, ScriptPromiseRes olver* resolver) const |
| 678 { | 709 { |
| 679 if (!ensureDeviceConfigured(resolver)) | 710 if (!ensureDeviceConfigured(resolver)) |
| 680 return false; | 711 return false; |
| 681 int interfaceIndex = findInterfaceIndex(interfaceNumber); | 712 int interfaceIndex = findInterfaceIndex(interfaceNumber); |
| 682 if (interfaceIndex == -1) { | 713 if (interfaceIndex == -1) |
| 683 resolver->reject(DOMException::create(NotFoundError, kInterfaceNotFound) ); | 714 resolver->reject(DOMException::create(NotFoundError, kInterfaceNotFound) ); |
| 684 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) { | 715 else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) |
| 685 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress)); | 716 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress)); |
| 686 } else if (!m_claimedInterfaces.get(interfaceIndex)) { | 717 else if (!m_claimedInterfaces.get(interfaceIndex)) |
| 687 resolver->reject(DOMException::create(InvalidStateError, "The specified interface has not been claimed.")); | 718 resolver->reject(DOMException::create(InvalidStateError, "The specified interface has not been claimed.")); |
| 688 } else { | 719 else |
| 689 return true; | 720 return true; |
| 690 } | |
| 691 return false; | 721 return false; |
| 692 } | 722 } |
| 693 | 723 |
| 694 bool USBDevice::ensureEndpointAvailable(bool inTransfer, uint8_t endpointNumber, ScriptPromiseResolver* resolver) const | 724 bool USBDevice::ensureEndpointAvailable(bool inTransfer, uint8_t endpointNumber, ScriptPromiseResolver* resolver) const |
| 695 { | 725 { |
| 696 // TODO(reillyg): Check endpoint availability once Blink is tracking which | 726 // TODO(reillyg): Check endpoint availability once Blink is tracking which |
| 697 // alternate interfaces are selected. | 727 // alternate interfaces are selected. |
| 698 return ensureDeviceConfigured(resolver); | 728 return ensureDeviceConfigured(resolver); |
| 699 } | 729 } |
| 700 | 730 |
| 701 bool USBDevice::anyInterfaceChangeInProgress() const | 731 bool USBDevice::anyInterfaceChangeInProgress() const |
| 702 { | 732 { |
| 703 for (size_t i = 0; i < m_interfaceStateChangeInProgress.size(); ++i) { | 733 for (size_t i = 0; i < m_interfaceStateChangeInProgress.size(); ++i) { |
| 704 if (m_interfaceStateChangeInProgress.quickGet(i)) | 734 if (m_interfaceStateChangeInProgress.quickGet(i)) |
| 705 return true; | 735 return true; |
| 706 } | 736 } |
| 707 return false; | 737 return false; |
| 708 } | 738 } |
| 709 | 739 |
| 710 } // namespace blink | 740 } // namespace blink |
| OLD | NEW |