Chromium Code Reviews| Index: third_party/WebKit/Source/modules/webusb/USB.cpp |
| diff --git a/third_party/WebKit/Source/modules/webusb/USB.cpp b/third_party/WebKit/Source/modules/webusb/USB.cpp |
| index 381cc39465b2861caa08086a73bd6712ff6da914..2a667a233ac589c73edd710477444068ce0e4559 100644 |
| --- a/third_party/WebKit/Source/modules/webusb/USB.cpp |
| +++ b/third_party/WebKit/Source/modules/webusb/USB.cpp |
| @@ -53,12 +53,7 @@ usb::DeviceFilterPtr convertDeviceFilter(const USBDeviceFilter& filter) { |
| } // namespace |
| USB::USB(LocalFrame& frame) |
| - : ContextLifecycleObserver(frame.document()), m_clientBinding(this) { |
| - frame.interfaceProvider()->getInterface(mojo::MakeRequest(&m_deviceManager)); |
| - m_deviceManager.set_connection_error_handler(convertToBaseCallback(WTF::bind( |
| - &USB::onDeviceManagerConnectionError, wrapWeakPersistent(this)))); |
| - m_deviceManager->SetClient(m_clientBinding.CreateInterfacePtrAndBind()); |
| -} |
| + : ContextLifecycleObserver(frame.document()), m_clientBinding(this) {} |
| USB::~USB() { |
| // |m_deviceManager| and |m_chooserService| may still be valid but there |
| @@ -77,6 +72,7 @@ void USB::dispose() { |
| ScriptPromise USB::getDevices(ScriptState* scriptState) { |
| ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| ScriptPromise promise = resolver->promise(); |
| + ensureDeviceManagerConnection(); |
| if (!m_deviceManager) { |
| resolver->reject(DOMException::create(NotSupportedError)); |
| } else { |
| @@ -91,20 +87,15 @@ ScriptPromise USB::getDevices(ScriptState* scriptState) { |
| ScriptPromise USB::requestDevice(ScriptState* scriptState, |
| const USBDeviceRequestOptions& options) { |
| - ExecutionContext* executionContext = scriptState->getExecutionContext(); |
| - |
| ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| ScriptPromise promise = resolver->promise(); |
| if (!m_chooserService) { |
| - LocalFrame* frame = executionContext->isDocument() |
| - ? toDocument(executionContext)->frame() |
| - : nullptr; |
| - if (!frame) { |
| + if (!frame()) { |
| resolver->reject(DOMException::create(NotSupportedError)); |
| return promise; |
| } |
| - frame->interfaceProvider()->getInterface( |
| + frame()->interfaceProvider()->getInterface( |
| mojo::MakeRequest(&m_chooserService)); |
| m_chooserService.set_connection_error_handler( |
| convertToBaseCallback(WTF::bind(&USB::onChooserServiceConnectionError, |
| @@ -180,16 +171,18 @@ void USB::onGetPermission(ScriptPromiseResolver* resolver, |
| return; |
| m_chooserServiceRequests.erase(requestEntry); |
| + ensureDeviceManagerConnection(); |
| if (!m_deviceManager) { |
| resolver->reject(DOMException::create(NotFoundError, kNoServiceError)); |
| return; |
| } |
| - if (deviceInfo) |
| + if (deviceInfo) { |
| resolver->resolve(getOrCreateDevice(std::move(deviceInfo))); |
| - else |
| + } else { |
| resolver->reject( |
| DOMException::create(NotFoundError, "No device selected.")); |
| + } |
| } |
| void USB::OnDeviceAdded(usb::DeviceInfoPtr deviceInfo) { |
| @@ -203,15 +196,17 @@ void USB::OnDeviceAdded(usb::DeviceInfoPtr deviceInfo) { |
| void USB::OnDeviceRemoved(usb::DeviceInfoPtr deviceInfo) { |
| String guid = deviceInfo->guid; |
| USBDevice* device = m_deviceCache.at(guid); |
| - if (!device) |
| + if (!device) { |
| device = USBDevice::create(std::move(deviceInfo), nullptr, |
| getExecutionContext()); |
| + } |
| dispatchEvent(USBConnectionEvent::create(EventTypeNames::disconnect, device)); |
| m_deviceCache.erase(guid); |
| } |
| void USB::onDeviceManagerConnectionError() { |
| m_deviceManager.reset(); |
| + m_clientBinding.Close(); |
| for (ScriptPromiseResolver* resolver : m_deviceManagerRequests) |
| resolver->reject(DOMException::create(NotFoundError, kNoServiceError)); |
| m_deviceManagerRequests.clear(); |
| @@ -224,6 +219,28 @@ void USB::onChooserServiceConnectionError() { |
| m_chooserServiceRequests.clear(); |
| } |
| +void USB::addedEventListener(const AtomicString& eventType, |
| + RegisteredEventListener& listener) { |
| + EventTargetWithInlineData::addedEventListener(eventType, listener); |
| + if (eventType == EventTypeNames::connect || |
| + eventType == EventTypeNames::disconnect) { |
| + ensureDeviceManagerConnection(); |
|
mcasas
2017/03/16 17:00:48
Can USB receive connect/disconnect events before
Reilly Grant (use Gerrit)
2017/03/16 17:43:14
Yes. An event will be dispatched whenever a device
|
| + } |
| +} |
| + |
| +void USB::ensureDeviceManagerConnection() { |
| + if (m_deviceManager || !frame()) |
| + return; |
| + |
| + frame()->interfaceProvider()->getInterface( |
| + mojo::MakeRequest(&m_deviceManager)); |
| + m_deviceManager.set_connection_error_handler(convertToBaseCallback(WTF::bind( |
| + &USB::onDeviceManagerConnectionError, wrapWeakPersistent(this)))); |
| + |
| + DCHECK(!m_clientBinding.is_bound()); |
| + m_deviceManager->SetClient(m_clientBinding.CreateInterfacePtrAndBind()); |
| +} |
| + |
| DEFINE_TRACE(USB) { |
| visitor->trace(m_deviceManagerRequests); |
| visitor->trace(m_chooserServiceRequests); |