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/USB.h" | 5 #include "modules/webusb/USB.h" |
6 | 6 |
7 #include "bindings/core/v8/ScriptPromise.h" | 7 #include "bindings/core/v8/ScriptPromise.h" |
8 #include "bindings/core/v8/ScriptPromiseResolver.h" | 8 #include "bindings/core/v8/ScriptPromiseResolver.h" |
9 #include "core/dom/DOMException.h" | 9 #include "core/dom/DOMException.h" |
10 #include "core/dom/Document.h" | 10 #include "core/dom/Document.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
53 ExecutionContext* context = resolver->getExecutionContext(); | 53 ExecutionContext* context = resolver->getExecutionContext(); |
54 return context && !context->activeDOMObjectsAreStopped(); | 54 return context && !context->activeDOMObjectsAreStopped(); |
55 } | 55 } |
56 | 56 |
57 } // namespace | 57 } // namespace |
58 | 58 |
59 USB::USB(LocalFrame& frame) | 59 USB::USB(LocalFrame& frame) |
60 : ContextLifecycleObserver(frame.document()) | 60 : ContextLifecycleObserver(frame.document()) |
61 { | 61 { |
62 frame.serviceRegistry()->connectToRemoteService(mojo::GetProxy(&m_deviceMana ger)); | 62 frame.serviceRegistry()->connectToRemoteService(mojo::GetProxy(&m_deviceMana ger)); |
63 m_deviceManager.set_connection_error_handler([this]() { | 63 m_deviceManager.set_connection_error_handler(createBaseCallback(bind(&USB::o nDeviceManagerConnectionError, WeakPersistentThisPointer<USB>(this)))); |
64 m_deviceManager.reset(); | |
65 for (ScriptPromiseResolver* resolver : m_deviceManagerRequests) { | |
66 if (isActive(resolver)) | |
67 resolver->reject(DOMException::create(NotFoundError, kNoServiceE rror)); | |
68 } | |
69 m_deviceManagerRequests.clear(); | |
70 }); | |
71 // Set up two sequential calls to GetDeviceChanges to avoid latency. | 64 // Set up two sequential calls to GetDeviceChanges to avoid latency. |
72 m_deviceManager->GetDeviceChanges(createBaseCallback(bind<usb::DeviceChangeN otificationPtr>(&USB::onDeviceChanges, this))); | 65 m_deviceManager->GetDeviceChanges(createBaseCallback(bind<usb::DeviceChangeN otificationPtr>(&USB::onDeviceChanges, WeakPersistentThisPointer<USB>(this)))); |
73 m_deviceManager->GetDeviceChanges(createBaseCallback(bind<usb::DeviceChangeN otificationPtr>(&USB::onDeviceChanges, this))); | 66 m_deviceManager->GetDeviceChanges(createBaseCallback(bind<usb::DeviceChangeN otificationPtr>(&USB::onDeviceChanges, WeakPersistentThisPointer<USB>(this)))); |
74 } | 67 } |
75 | 68 |
76 USB::~USB() | 69 USB::~USB() |
77 { | 70 { |
78 DCHECK(!m_deviceManager); | 71 // |m_deviceManager| and |m_chooserService| may still be valid but there |
72 // should be no more outstanding requests to them because each holds a | |
73 // persistent handle to this object. | |
79 DCHECK(m_deviceManagerRequests.isEmpty()); | 74 DCHECK(m_deviceManagerRequests.isEmpty()); |
80 DCHECK(!m_chooserService); | |
81 DCHECK(m_chooserServiceRequests.isEmpty()); | 75 DCHECK(m_chooserServiceRequests.isEmpty()); |
82 } | 76 } |
83 | 77 |
84 ScriptPromise USB::getDevices(ScriptState* scriptState) | 78 ScriptPromise USB::getDevices(ScriptState* scriptState) |
85 { | 79 { |
86 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 80 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
87 ScriptPromise promise = resolver->promise(); | 81 ScriptPromise promise = resolver->promise(); |
88 if (!m_deviceManager) { | 82 if (!m_deviceManager) { |
89 resolver->reject(DOMException::create(NotSupportedError)); | 83 resolver->reject(DOMException::create(NotSupportedError)); |
90 } else { | 84 } else { |
(...skipping 13 matching lines...) Expand all Loading... | |
104 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 98 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
105 ScriptPromise promise = resolver->promise(); | 99 ScriptPromise promise = resolver->promise(); |
106 | 100 |
107 if (!m_chooserService) { | 101 if (!m_chooserService) { |
108 LocalFrame* frame = getExecutionContext() ? toDocument(getExecutionConte xt())->frame() : nullptr; | 102 LocalFrame* frame = getExecutionContext() ? toDocument(getExecutionConte xt())->frame() : nullptr; |
109 if (!frame) { | 103 if (!frame) { |
110 resolver->reject(DOMException::create(NotSupportedError)); | 104 resolver->reject(DOMException::create(NotSupportedError)); |
111 return promise; | 105 return promise; |
112 } | 106 } |
113 frame->serviceRegistry()->connectToRemoteService(mojo::GetProxy(&m_choos erService)); | 107 frame->serviceRegistry()->connectToRemoteService(mojo::GetProxy(&m_choos erService)); |
114 m_chooserService.set_connection_error_handler([this]() { | 108 m_chooserService.set_connection_error_handler(createBaseCallback(bind(&U SB::onChooserServiceConnectionError, WeakPersistentThisPointer<USB>(this)))); |
115 m_chooserService.reset(); | |
116 for (ScriptPromiseResolver* resolver : m_chooserServiceRequests) { | |
117 if (isActive(resolver)) | |
118 resolver->reject(DOMException::create(NotFoundError, kNoServ iceError)); | |
119 } | |
120 m_chooserServiceRequests.clear(); | |
121 }); | |
122 } | 109 } |
123 | 110 |
124 String errorMessage; | 111 String errorMessage; |
125 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) { | 112 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) { |
126 resolver->reject(DOMException::create(SecurityError, errorMessage)); | 113 resolver->reject(DOMException::create(SecurityError, errorMessage)); |
127 } else if (!UserGestureIndicator::consumeUserGesture()) { | 114 } else if (!UserGestureIndicator::consumeUserGesture()) { |
128 resolver->reject(DOMException::create(SecurityError, "Must be handling a user gesture to show a permission request.")); | 115 resolver->reject(DOMException::create(SecurityError, "Must be handling a user gesture to show a permission request.")); |
129 } else { | 116 } else { |
130 Vector<usb::DeviceFilterPtr> filters; | 117 Vector<usb::DeviceFilterPtr> filters; |
131 if (options.hasFilters()) { | 118 if (options.hasFilters()) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
181 usb::DevicePtr device; | 168 usb::DevicePtr device; |
182 m_deviceManager->GetDevice(deviceInfo->guid, mojo::GetProxy(&device)); | 169 m_deviceManager->GetDevice(deviceInfo->guid, mojo::GetProxy(&device)); |
183 resolver->resolve(USBDevice::create(std::move(deviceInfo), std::move(dev ice), resolver->getExecutionContext())); | 170 resolver->resolve(USBDevice::create(std::move(deviceInfo), std::move(dev ice), resolver->getExecutionContext())); |
184 } else { | 171 } else { |
185 resolver->reject(DOMException::create(NotFoundError, "No device selected .")); | 172 resolver->reject(DOMException::create(NotFoundError, "No device selected .")); |
186 } | 173 } |
187 } | 174 } |
188 | 175 |
189 void USB::onDeviceChanges(usb::DeviceChangeNotificationPtr notification) | 176 void USB::onDeviceChanges(usb::DeviceChangeNotificationPtr notification) |
190 { | 177 { |
191 m_deviceManager->GetDeviceChanges(createBaseCallback(bind<usb::DeviceChangeN otificationPtr>(&USB::onDeviceChanges, this))); | 178 m_deviceManager->GetDeviceChanges(createBaseCallback(bind<usb::DeviceChangeN otificationPtr>(&USB::onDeviceChanges, WeakPersistentThisPointer<USB>(this)))); |
192 for (auto& deviceInfo : notification->devices_added.PassStorage()) { | 179 for (auto& deviceInfo : notification->devices_added.PassStorage()) { |
193 usb::DevicePtr device; | 180 usb::DevicePtr device; |
194 m_deviceManager->GetDevice(deviceInfo->guid, mojo::GetProxy(&device)); | 181 m_deviceManager->GetDevice(deviceInfo->guid, mojo::GetProxy(&device)); |
195 dispatchEvent(USBConnectionEvent::create(EventTypeNames::connect, USBDev ice::create(std::move(deviceInfo), std::move(device), getExecutionContext()))); | 182 dispatchEvent(USBConnectionEvent::create(EventTypeNames::connect, USBDev ice::create(std::move(deviceInfo), std::move(device), getExecutionContext()))); |
196 } | 183 } |
197 for (auto& deviceInfo : notification->devices_removed.PassStorage()) | 184 for (auto& deviceInfo : notification->devices_removed.PassStorage()) |
198 dispatchEvent(USBConnectionEvent::create(EventTypeNames::disconnect, USB Device::create(std::move(deviceInfo), nullptr, getExecutionContext()))); | 185 dispatchEvent(USBConnectionEvent::create(EventTypeNames::disconnect, USB Device::create(std::move(deviceInfo), nullptr, getExecutionContext()))); |
199 } | 186 } |
200 | 187 |
188 void USB::onDeviceManagerConnectionError() | |
189 { | |
190 m_deviceManager.reset(); | |
191 for (ScriptPromiseResolver* resolver : m_deviceManagerRequests) { | |
esprehn
2016/04/23 00:54:02
seems like this needs to be more centralized, doin
| |
192 if (isActive(resolver)) | |
193 resolver->reject(DOMException::create(NotFoundError, kNoServiceError )); | |
194 } | |
195 m_deviceManagerRequests.clear(); | |
196 } | |
197 | |
198 void USB::onChooserServiceConnectionError() | |
199 { | |
200 m_chooserService.reset(); | |
201 for (ScriptPromiseResolver* resolver : m_chooserServiceRequests) { | |
202 if (isActive(resolver)) | |
203 resolver->reject(DOMException::create(NotFoundError, kNoServiceError )); | |
204 } | |
205 m_chooserServiceRequests.clear(); | |
206 } | |
207 | |
201 DEFINE_TRACE(USB) | 208 DEFINE_TRACE(USB) |
202 { | 209 { |
203 EventTargetWithInlineData::trace(visitor); | 210 EventTargetWithInlineData::trace(visitor); |
204 ContextLifecycleObserver::trace(visitor); | 211 ContextLifecycleObserver::trace(visitor); |
205 visitor->trace(m_deviceManagerRequests); | 212 visitor->trace(m_deviceManagerRequests); |
206 visitor->trace(m_chooserServiceRequests); | 213 visitor->trace(m_chooserServiceRequests); |
207 } | 214 } |
208 | 215 |
209 } // namespace blink | 216 } // namespace blink |
OLD | NEW |