Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: third_party/WebKit/Source/modules/webusb/USBDevice.cpp

Issue 1850023002: Consume Mojo services directly in Blink's WebUSB implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Don't do assignments in if statements. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
8 #include "bindings/core/v8/ScriptPromise.h" 7 #include "bindings/core/v8/ScriptPromise.h"
9 #include "bindings/core/v8/ScriptPromiseResolver.h" 8 #include "bindings/core/v8/ScriptPromiseResolver.h"
10 #include "bindings/core/v8/ToV8.h" 9 #include "bindings/core/v8/ToV8.h"
11 #include "core/dom/DOMArrayBuffer.h" 10 #include "core/dom/DOMArrayBuffer.h"
12 #include "core/dom/DOMArrayBufferView.h" 11 #include "core/dom/DOMArrayBufferView.h"
13 #include "core/dom/DOMException.h" 12 #include "core/dom/DOMException.h"
14 #include "core/dom/ExceptionCode.h" 13 #include "core/dom/ExceptionCode.h"
15 #include "modules/webusb/USBConfiguration.h" 14 #include "modules/webusb/USBConfiguration.h"
16 #include "modules/webusb/USBControlTransferParameters.h" 15 #include "modules/webusb/USBControlTransferParameters.h"
17 #include "modules/webusb/USBError.h"
18 #include "modules/webusb/USBInTransferResult.h" 16 #include "modules/webusb/USBInTransferResult.h"
19 #include "modules/webusb/USBIsochronousInTransferResult.h" 17 #include "modules/webusb/USBIsochronousInTransferResult.h"
20 #include "modules/webusb/USBIsochronousOutTransferResult.h" 18 #include "modules/webusb/USBIsochronousOutTransferResult.h"
21 #include "modules/webusb/USBOutTransferResult.h" 19 #include "modules/webusb/USBOutTransferResult.h"
22 #include "public/platform/modules/webusb/WebUSBTransferInfo.h" 20 #include "platform/MojoHelper.h"
23 #include "wtf/Assertions.h" 21 #include "wtf/Assertions.h"
24 22
23 namespace usb = device::usb::wtf;
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 kDeviceUnavailable[] = "Device unavailable.";
30 const char kInterfaceNotFound[] = "The interface number provided is not supporte d by the device in its current configuration."; 31 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."; 32 const char kInterfaceStateChangeInProgress[] = "An operation that changes interf ace state is in progress.";
32 const char kOpenRequired[] = "The device must be opened first."; 33 const char kOpenRequired[] = "The device must be opened first.";
33 34
34 String convertTransferStatus(const WebUSBTransferInfo::Status& status) 35 DOMException* convertFatalTransferStatus(const usb::TransferStatus& status)
35 { 36 {
36 switch (status) { 37 switch (status) {
37 case WebUSBTransferInfo::Status::Ok: 38 case usb::TransferStatus::TRANSFER_ERROR:
39 return DOMException::create(NetworkError, "A transfer error has occured. ");
40 case usb::TransferStatus::PERMISSION_DENIED:
41 return DOMException::create(SecurityError, "The transfer was not allowed .");
42 case usb::TransferStatus::TIMEOUT:
43 return DOMException::create(TimeoutError, "The transfer timed out.");
44 case usb::TransferStatus::CANCELLED:
45 return DOMException::create(AbortError, "The transfer was cancelled.");
46 case usb::TransferStatus::DISCONNECT:
47 return DOMException::create(NotFoundError, kDeviceUnavailable);
48 case usb::TransferStatus::COMPLETED:
49 case usb::TransferStatus::STALLED:
50 case usb::TransferStatus::BABBLE:
51 case usb::TransferStatus::SHORT_PACKET:
52 return nullptr;
53 default:
54 ASSERT_NOT_REACHED();
55 return nullptr;
56 }
57 }
58
59 String convertTransferStatus(const usb::TransferStatus& status)
60 {
61 switch (status) {
62 case usb::TransferStatus::COMPLETED:
63 case usb::TransferStatus::SHORT_PACKET:
38 return "ok"; 64 return "ok";
39 case WebUSBTransferInfo::Status::Stall: 65 case usb::TransferStatus::STALLED:
40 return "stall"; 66 return "stall";
41 case WebUSBTransferInfo::Status::Babble: 67 case usb::TransferStatus::BABBLE:
42 return "babble"; 68 return "babble";
43 default: 69 default:
44 ASSERT_NOT_REACHED(); 70 ASSERT_NOT_REACHED();
45 return ""; 71 return "";
46 } 72 }
47 } 73 }
48 74
49 class OpenClosePromiseAdapter : public WebCallbacks<void, const WebUSBError&> { 75 mojo::WTFArray<uint8_t> convertBufferSource(const ArrayBufferOrArrayBufferView& buffer)
50 public: 76 {
51 OpenClosePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, bool desiredState) 77 ASSERT(!buffer.isNull());
52 : m_device(device) 78 Vector<uint8_t> vector;
53 , m_resolver(resolver) 79 if (buffer.isArrayBuffer())
54 , m_desiredState(desiredState) 80 vector.append(static_cast<uint8_t*>(buffer.getAsArrayBuffer()->data()), buffer.getAsArrayBuffer()->byteLength());
55 { 81 else
56 } 82 vector.append(static_cast<uint8_t*>(buffer.getAsArrayBufferView()->baseA ddress()), buffer.getAsArrayBufferView()->byteLength());
83 return mojo::WTFArray<uint8_t>(std::move(vector));
84 }
57 85
58 void onSuccess() override 86 bool isActive(ScriptPromiseResolver* resolver)
59 { 87 {
60 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) 88 ExecutionContext* context = resolver->getExecutionContext();
61 return; 89 return context && !context->activeDOMObjectsAreStopped();
62 90 }
63 m_device->onDeviceOpenedOrClosed(m_desiredState);
64 m_resolver->resolve();
65 }
66
67 void onError(const WebUSBError& e) override
68 {
69 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped())
70 return;
71 m_device->onDeviceOpenedOrClosed(!m_desiredState);
72 m_resolver->reject(USBError::take(m_resolver, e));
73 }
74
75 private:
76 Persistent<USBDevice> m_device;
77 Persistent<ScriptPromiseResolver> m_resolver;
78 bool m_desiredState; // true: open, false: closed
79 };
80
81 class SelectConfigurationPromiseAdapter : public WebCallbacks<void, const WebUSB Error&> {
82 public:
83 SelectConfigurationPromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, size_t configurationIndex)
84 : m_device(device)
85 , m_resolver(resolver)
86 , m_configurationIndex(configurationIndex)
87 {
88 }
89
90 void onSuccess() override
91 {
92 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped())
93 return;
94 m_device->onConfigurationSelected(true /* success */, m_configurationInd ex);
95 m_resolver->resolve();
96 }
97
98 void onError(const WebUSBError& e) override
99 {
100 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped())
101 return;
102 m_device->onConfigurationSelected(false /* failure */, m_configurationIn dex);
103 m_resolver->reject(USBError::take(m_resolver, e));
104 }
105
106 private:
107 Persistent<USBDevice> m_device;
108 Persistent<ScriptPromiseResolver> m_resolver;
109 size_t m_configurationIndex;
110 };
111
112 class ClaimInterfacePromiseAdapter : public WebCallbacks<void, const WebUSBError &> {
113 public:
114 ClaimInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resol ver, size_t interfaceIndex, bool desiredState)
115 : m_device(device)
116 , m_resolver(resolver)
117 , m_interfaceIndex(interfaceIndex)
118 , m_desiredState(desiredState)
119 {
120 }
121
122 void onSuccess() override
123 {
124 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped())
125 return;
126 m_device->onInterfaceClaimedOrUnclaimed(m_desiredState, m_interfaceIndex );
127 m_resolver->resolve();
128 }
129
130 void onError(const WebUSBError& e) override
131 {
132 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped())
133 return;
134 m_device->onInterfaceClaimedOrUnclaimed(!m_desiredState, m_interfaceInde x);
135 m_resolver->reject(USBError::take(m_resolver, e));
136 }
137
138 private:
139 Persistent<USBDevice> m_device;
140 Persistent<ScriptPromiseResolver> m_resolver;
141 size_t m_interfaceIndex;
142 bool m_desiredState; // true: claimed, false: unclaimed
143 };
144
145 class SelectAlternateInterfacePromiseAdapter : public WebCallbacks<void, const W ebUSBError&> {
146 public:
147 SelectAlternateInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResol ver* resolver, size_t interfaceIndex, size_t alternateIndex)
148 : m_device(device)
149 , m_resolver(resolver)
150 , m_interfaceIndex(interfaceIndex)
151 , m_alternateIndex(alternateIndex)
152 {
153 }
154
155 void onSuccess() override
156 {
157 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped())
158 return;
159 m_device->onAlternateInterfaceSelected(true /* success */, m_interfaceIn dex, m_alternateIndex);
160 m_resolver->resolve();
161 }
162
163 void onError(const WebUSBError& e) override
164 {
165 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped())
166 return;
167 m_device->onAlternateInterfaceSelected(false /* failure */, m_interfaceI ndex, m_alternateIndex);
168 m_resolver->reject(USBError::take(m_resolver, e));
169 }
170
171 private:
172 Persistent<USBDevice> m_device;
173 Persistent<ScriptPromiseResolver> m_resolver;
174 size_t m_interfaceIndex;
175 size_t m_alternateIndex;
176 };
177
178 class InputTransferResult {
179 WTF_MAKE_NONCOPYABLE(InputTransferResult);
180 public:
181 using WebType = OwnPtr<WebUSBTransferInfo>;
182
183 static USBInTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTr ansferInfo> webTransferInfo)
184 {
185 ASSERT(webTransferInfo->status.size() == 1);
186 return USBInTransferResult::create(convertTransferStatus(webTransferInfo ->status[0]), webTransferInfo->data);
187 }
188
189 private:
190 InputTransferResult() = delete;
191 };
192
193 class OutputTransferResult {
194 WTF_MAKE_NONCOPYABLE(OutputTransferResult);
195 public:
196 using WebType = OwnPtr<WebUSBTransferInfo>;
197
198 static USBOutTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBT ransferInfo> webTransferInfo)
199 {
200 ASSERT(webTransferInfo->status.size() == 1);
201 ASSERT(webTransferInfo->bytesTransferred.size() == 1);
202 return USBOutTransferResult::create(convertTransferStatus(webTransferInf o->status[0]), webTransferInfo->bytesTransferred[0]);
203 }
204
205 private:
206 OutputTransferResult() = delete;
207 };
208
209 class IsochronousInputTransferResult {
210 WTF_MAKE_NONCOPYABLE(IsochronousInputTransferResult);
211
212 public:
213 using WebType = OwnPtr<WebUSBTransferInfo>;
214
215 static USBIsochronousInTransferResult* take(ScriptPromiseResolver*, PassOwnP tr<WebUSBTransferInfo> webTransferInfo)
216 {
217 ASSERT(webTransferInfo->status.size() == webTransferInfo->packetLength.s ize() && webTransferInfo->packetLength.size() == webTransferInfo->bytesTransferr ed.size());
218 DOMArrayBuffer* buffer = DOMArrayBuffer::create(webTransferInfo->data.da ta(), webTransferInfo->data.size());
219 HeapVector<Member<USBIsochronousInTransferPacket>> packets(webTransferIn fo->status.size());
220 size_t byteOffset = 0;
221 for (size_t i = 0; i < webTransferInfo->status.size(); ++i) {
222 packets[i] = USBIsochronousInTransferPacket::create(convertTransferS tatus(webTransferInfo->status[i]), DOMDataView::create(buffer, byteOffset, webTr ansferInfo->bytesTransferred[i]));
223 byteOffset += webTransferInfo->packetLength[i];
224 }
225 return USBIsochronousInTransferResult::create(buffer, packets);
226 }
227 };
228
229 class IsochronousOutputTransferResult {
230 WTF_MAKE_NONCOPYABLE(IsochronousOutputTransferResult);
231
232 public:
233 using WebType = OwnPtr<WebUSBTransferInfo>;
234
235 static USBIsochronousOutTransferResult* take(ScriptPromiseResolver*, PassOwn Ptr<WebUSBTransferInfo> webTransferInfo)
236 {
237 ASSERT(webTransferInfo->status.size() == webTransferInfo->bytesTransferr ed.size());
238 HeapVector<Member<USBIsochronousOutTransferPacket>> packets(webTransferI nfo->status.size());
239 for (size_t i = 0; i < webTransferInfo->status.size(); ++i)
240 packets[i] = USBIsochronousOutTransferPacket::create(convertTransfer Status(webTransferInfo->status[i]), webTransferInfo->bytesTransferred[i]);
241 return USBIsochronousOutTransferResult::create(packets);
242 }
243 };
244
245 class BufferSource {
246 WTF_MAKE_NONCOPYABLE(BufferSource);
247 public:
248 BufferSource(const ArrayBufferOrArrayBufferView& buffer) : m_buffer(buffer)
249 {
250 ASSERT(!m_buffer.isNull());
251 }
252
253 uint8_t* data() const
254 {
255 if (m_buffer.isArrayBuffer())
256 return static_cast<uint8_t*>(m_buffer.getAsArrayBuffer()->data());
257 return static_cast<uint8_t*>(m_buffer.getAsArrayBufferView()->baseAddres s());
258 }
259
260 unsigned size() const
261 {
262 if (m_buffer.isArrayBuffer())
263 return m_buffer.getAsArrayBuffer()->byteLength();
264 return m_buffer.getAsArrayBufferView()->byteLength();
265 }
266
267 private:
268 const ArrayBufferOrArrayBufferView& m_buffer;
269 };
270 91
271 } // namespace 92 } // namespace
272 93
273 // static 94 USBDevice::USBDevice(usb::DeviceInfoPtr deviceInfo, usb::DevicePtr device, Execu tionContext* context)
274 USBDevice* USBDevice::take(ScriptPromiseResolver* resolver, PassOwnPtr<WebUSBDev ice> device)
275 {
276 return USBDevice::create(device, resolver->getExecutionContext());
277 }
278
279 USBDevice::USBDevice(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context)
280 : ContextLifecycleObserver(context) 95 : ContextLifecycleObserver(context)
281 , m_device(device) 96 , m_deviceInfo(std::move(deviceInfo))
97 , m_device(std::move(device))
282 , m_opened(false) 98 , m_opened(false)
283 , m_deviceStateChangeInProgress(false) 99 , m_deviceStateChangeInProgress(false)
284 , m_configurationIndex(-1) 100 , m_configurationIndex(-1)
285 , m_inEndpoints(15)
286 , m_outEndpoints(15)
287 { 101 {
288 int configurationIndex = findConfigurationIndex(info().activeConfiguration); 102 if (m_device) {
103 m_device.set_connection_error_handler([this]() {
104 m_device.reset();
105 m_opened = false;
106 for (ScriptPromiseResolver* resolver : m_deviceRequests) {
107 if (isActive(resolver))
108 resolver->reject(DOMException::create(NotFoundError, kDevice Unavailable));
109 }
110 });
111 }
112 int configurationIndex = findConfigurationIndex(info().active_configuration) ;
289 if (configurationIndex != -1) 113 if (configurationIndex != -1)
290 onConfigurationSelected(true /* success */, configurationIndex); 114 onConfigurationSelected(true /* success */, configurationIndex);
291 } 115 }
292 116
293 void USBDevice::onDeviceOpenedOrClosed(bool opened) 117 USBDevice::~USBDevice()
294 { 118 {
295 m_opened = opened; 119 DCHECK(!m_device);
296 m_deviceStateChangeInProgress = false; 120 DCHECK(m_deviceRequests.isEmpty());
297 }
298
299 void USBDevice::onConfigurationSelected(bool success, size_t configurationIndex)
300 {
301 if (success) {
302 m_configurationIndex = configurationIndex;
303 size_t numInterfaces = info().configurations[m_configurationIndex].inter faces.size();
304 m_claimedInterfaces.clearAll();
305 m_claimedInterfaces.resize(numInterfaces);
306 m_interfaceStateChangeInProgress.clearAll();
307 m_interfaceStateChangeInProgress.resize(numInterfaces);
308 m_selectedAlternates.resize(numInterfaces);
309 m_selectedAlternates.fill(0);
310 m_inEndpoints.clearAll();
311 m_outEndpoints.clearAll();
312 }
313 m_deviceStateChangeInProgress = false;
314 }
315
316 void USBDevice::onInterfaceClaimedOrUnclaimed(bool claimed, size_t interfaceInde x)
317 {
318 if (claimed) {
319 m_claimedInterfaces.set(interfaceIndex);
320 } else {
321 m_claimedInterfaces.clear(interfaceIndex);
322 m_selectedAlternates[interfaceIndex] = 0;
323 }
324 setEndpointsForInterface(interfaceIndex, claimed);
325 m_interfaceStateChangeInProgress.clear(interfaceIndex);
326 }
327
328 void USBDevice::onAlternateInterfaceSelected(bool success, size_t interfaceIndex , size_t alternateIndex)
329 {
330 if (success)
331 m_selectedAlternates[interfaceIndex] = alternateIndex;
332 setEndpointsForInterface(interfaceIndex, success);
333 m_interfaceStateChangeInProgress.clear(interfaceIndex);
334 } 121 }
335 122
336 bool USBDevice::isInterfaceClaimed(size_t configurationIndex, size_t interfaceIn dex) const 123 bool USBDevice::isInterfaceClaimed(size_t configurationIndex, size_t interfaceIn dex) const
337 { 124 {
338 return m_configurationIndex != -1 && static_cast<size_t>(m_configurationInde x) == configurationIndex && m_claimedInterfaces.get(interfaceIndex); 125 return m_configurationIndex != -1 && static_cast<size_t>(m_configurationInde x) == configurationIndex && m_claimedInterfaces.get(interfaceIndex);
339 } 126 }
340 127
341 size_t USBDevice::selectedAlternateInterface(size_t interfaceIndex) const 128 size_t USBDevice::selectedAlternateInterface(size_t interfaceIndex) const
342 { 129 {
343 return m_selectedAlternates[interfaceIndex]; 130 return m_selectedAlternates[interfaceIndex];
344 } 131 }
345 132
346 USBConfiguration* USBDevice::configuration() const 133 USBConfiguration* USBDevice::configuration() const
347 { 134 {
348 if (m_configurationIndex != -1) 135 if (m_configurationIndex != -1)
349 return USBConfiguration::create(this, m_configurationIndex); 136 return USBConfiguration::create(this, m_configurationIndex);
350 return nullptr; 137 return nullptr;
351 } 138 }
352 139
353 HeapVector<Member<USBConfiguration>> USBDevice::configurations() const 140 HeapVector<Member<USBConfiguration>> USBDevice::configurations() const
354 { 141 {
355 HeapVector<Member<USBConfiguration>> configurations;
356 size_t numConfigurations = info().configurations.size(); 142 size_t numConfigurations = info().configurations.size();
143 HeapVector<Member<USBConfiguration>> configurations(numConfigurations);
357 for (size_t i = 0; i < numConfigurations; ++i) 144 for (size_t i = 0; i < numConfigurations; ++i)
358 configurations.append(USBConfiguration::create(this, i)); 145 configurations[i] = USBConfiguration::create(this, i);
359 return configurations; 146 return configurations;
360 } 147 }
361 148
362 ScriptPromise USBDevice::open(ScriptState* scriptState) 149 ScriptPromise USBDevice::open(ScriptState* scriptState)
363 { 150 {
364 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 151 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
365 ScriptPromise promise = resolver->promise(); 152 ScriptPromise promise = resolver->promise();
366 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) { 153 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
367 if (m_opened) { 154 if (m_opened) {
368 resolver->resolve(); 155 resolver->resolve();
369 } else { 156 } else {
370 m_deviceStateChangeInProgress = true; 157 m_deviceStateChangeInProgress = true;
371 m_device->open(new OpenClosePromiseAdapter(this, resolver, true /* o pen */)); 158 m_deviceRequests.add(resolver);
159 m_device->Open(createBaseCallback(bind<usb::OpenDeviceError>(&USBDev ice::asyncOpen, this, resolver)));
372 } 160 }
373 } 161 }
374 return promise; 162 return promise;
375 } 163 }
376 164
377 ScriptPromise USBDevice::close(ScriptState* scriptState) 165 ScriptPromise USBDevice::close(ScriptState* scriptState)
378 { 166 {
379 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 167 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
380 ScriptPromise promise = resolver->promise(); 168 ScriptPromise promise = resolver->promise();
381 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) { 169 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
382 if (!m_opened) { 170 if (!m_opened) {
383 resolver->resolve(); 171 resolver->resolve();
384 } else { 172 } else {
385 m_deviceStateChangeInProgress = true; 173 m_deviceStateChangeInProgress = true;
386 m_device->close(new OpenClosePromiseAdapter(this, resolver, false /* closed */)); 174 m_deviceRequests.add(resolver);
175 m_device->Close(createBaseCallback(bind(&USBDevice::asyncClose, this , resolver)));
387 } 176 }
388 } 177 }
389 return promise; 178 return promise;
390 } 179 }
391 180
392 ScriptPromise USBDevice::selectConfiguration(ScriptState* scriptState, uint8_t c onfigurationValue) 181 ScriptPromise USBDevice::selectConfiguration(ScriptState* scriptState, uint8_t c onfigurationValue)
393 { 182 {
394 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 183 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
395 ScriptPromise promise = resolver->promise(); 184 ScriptPromise promise = resolver->promise();
396 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) { 185 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
397 if (!m_opened) { 186 if (!m_opened) {
398 resolver->reject(DOMException::create(InvalidStateError, kOpenRequir ed)); 187 resolver->reject(DOMException::create(InvalidStateError, kOpenRequir ed));
399 } else { 188 } else {
400 int configurationIndex = findConfigurationIndex(configurationValue); 189 int configurationIndex = findConfigurationIndex(configurationValue);
401 if (configurationIndex == -1) { 190 if (configurationIndex == -1) {
402 resolver->reject(DOMException::create(NotFoundError, "The config uration value provided is not supported by the device.")); 191 resolver->reject(DOMException::create(NotFoundError, "The config uration value provided is not supported by the device."));
403 } else if (m_configurationIndex == configurationIndex) { 192 } else if (m_configurationIndex == configurationIndex) {
404 resolver->resolve(); 193 resolver->resolve();
405 } else { 194 } else {
406 m_deviceStateChangeInProgress = true; 195 m_deviceStateChangeInProgress = true;
407 m_device->setConfiguration(configurationValue, new SelectConfigu rationPromiseAdapter(this, resolver, configurationIndex)); 196 m_deviceRequests.add(resolver);
197 m_device->SetConfiguration(configurationValue, createBaseCallbac k(bind<bool>(&USBDevice::asyncSelectConfiguration, this, configurationIndex, res olver)));
408 } 198 }
409 } 199 }
410 } 200 }
411 return promise; 201 return promise;
412 } 202 }
413 203
414 ScriptPromise USBDevice::claimInterface(ScriptState* scriptState, uint8_t interf aceNumber) 204 ScriptPromise USBDevice::claimInterface(ScriptState* scriptState, uint8_t interf aceNumber)
415 { 205 {
416 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 206 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
417 ScriptPromise promise = resolver->promise(); 207 ScriptPromise promise = resolver->promise();
418 if (ensureDeviceConfigured(resolver)) { 208 if (ensureDeviceConfigured(resolver)) {
419 int interfaceIndex = findInterfaceIndex(interfaceNumber); 209 int interfaceIndex = findInterfaceIndex(interfaceNumber);
420 if (interfaceIndex == -1) { 210 if (interfaceIndex == -1) {
421 resolver->reject(DOMException::create(NotFoundError, kInterfaceNotFo und)); 211 resolver->reject(DOMException::create(NotFoundError, kInterfaceNotFo und));
422 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) { 212 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) {
423 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS tateChangeInProgress)); 213 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS tateChangeInProgress));
424 } else if (m_claimedInterfaces.get(interfaceIndex)) { 214 } else if (m_claimedInterfaces.get(interfaceIndex)) {
425 resolver->resolve(); 215 resolver->resolve();
426 } else { 216 } else {
427 m_interfaceStateChangeInProgress.set(interfaceIndex); 217 m_interfaceStateChangeInProgress.set(interfaceIndex);
428 m_device->claimInterface(interfaceNumber, new ClaimInterfacePromiseA dapter(this, resolver, interfaceIndex, true /* claim */)); 218 m_deviceRequests.add(resolver);
219 m_device->ClaimInterface(interfaceNumber, createBaseCallback(bind<bo ol>(&USBDevice::asyncClaimInterface, this, interfaceIndex, resolver)));
429 } 220 }
430 } 221 }
431 return promise; 222 return promise;
432 } 223 }
433 224
434 ScriptPromise USBDevice::releaseInterface(ScriptState* scriptState, uint8_t inte rfaceNumber) 225 ScriptPromise USBDevice::releaseInterface(ScriptState* scriptState, uint8_t inte rfaceNumber)
435 { 226 {
436 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 227 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
437 ScriptPromise promise = resolver->promise(); 228 ScriptPromise promise = resolver->promise();
438 if (ensureDeviceConfigured(resolver)) { 229 if (ensureDeviceConfigured(resolver)) {
439 int interfaceIndex = findInterfaceIndex(interfaceNumber); 230 int interfaceIndex = findInterfaceIndex(interfaceNumber);
440 if (interfaceIndex == -1) { 231 if (interfaceIndex == -1) {
441 resolver->reject(DOMException::create(NotFoundError, "The interface number provided is not supported by the device in its current configuration.")); 232 resolver->reject(DOMException::create(NotFoundError, "The interface number provided is not supported by the device in its current configuration."));
442 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) { 233 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) {
443 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS tateChangeInProgress)); 234 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS tateChangeInProgress));
444 } else if (!m_claimedInterfaces.get(interfaceIndex)) { 235 } else if (!m_claimedInterfaces.get(interfaceIndex)) {
445 resolver->resolve(); 236 resolver->resolve();
446 } else { 237 } else {
447 // Mark this interface's endpoints unavailable while its state is 238 // Mark this interface's endpoints unavailable while its state is
448 // changing. 239 // changing.
449 setEndpointsForInterface(interfaceIndex, false); 240 setEndpointsForInterface(interfaceIndex, false);
450 m_interfaceStateChangeInProgress.set(interfaceIndex); 241 m_interfaceStateChangeInProgress.set(interfaceIndex);
451 m_device->releaseInterface(interfaceNumber, new ClaimInterfacePromis eAdapter(this, resolver, interfaceIndex, false /* release */)); 242 m_deviceRequests.add(resolver);
243 m_device->ReleaseInterface(interfaceNumber, createBaseCallback(bind< bool>(&USBDevice::asyncReleaseInterface, this, interfaceIndex, resolver)));
452 } 244 }
453 } 245 }
454 return promise; 246 return promise;
455 } 247 }
456 248
457 ScriptPromise USBDevice::selectAlternateInterface(ScriptState* scriptState, uint 8_t interfaceNumber, uint8_t alternateSetting) 249 ScriptPromise USBDevice::selectAlternateInterface(ScriptState* scriptState, uint 8_t interfaceNumber, uint8_t alternateSetting)
458 { 250 {
459 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 251 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
460 ScriptPromise promise = resolver->promise(); 252 ScriptPromise promise = resolver->promise();
461 if (ensureInterfaceClaimed(interfaceNumber, resolver)) { 253 if (ensureInterfaceClaimed(interfaceNumber, resolver)) {
462 // TODO(reillyg): This is duplicated work. 254 // TODO(reillyg): This is duplicated work.
463 int interfaceIndex = findInterfaceIndex(interfaceNumber); 255 int interfaceIndex = findInterfaceIndex(interfaceNumber);
464 ASSERT(interfaceIndex != -1); 256 ASSERT(interfaceIndex != -1);
465 int alternateIndex = findAlternateIndex(interfaceIndex, alternateSetting ); 257 int alternateIndex = findAlternateIndex(interfaceIndex, alternateSetting );
466 if (alternateIndex == -1) { 258 if (alternateIndex == -1) {
467 resolver->reject(DOMException::create(NotFoundError, "The alternate setting provided is not supported by the device in its current configuration.")) ; 259 resolver->reject(DOMException::create(NotFoundError, "The alternate setting provided is not supported by the device in its current configuration.")) ;
468 } else { 260 } else {
469 // Mark this old alternate interface's endpoints unavailable while 261 // Mark this old alternate interface's endpoints unavailable while
470 // the change is in progress. 262 // the change is in progress.
471 setEndpointsForInterface(interfaceIndex, false); 263 setEndpointsForInterface(interfaceIndex, false);
472 m_interfaceStateChangeInProgress.set(interfaceIndex); 264 m_interfaceStateChangeInProgress.set(interfaceIndex);
473 m_device->setInterface(interfaceNumber, alternateSetting, new Select AlternateInterfacePromiseAdapter(this, resolver, interfaceIndex, alternateIndex) ); 265 m_deviceRequests.add(resolver);
266 m_device->SetInterfaceAlternateSetting(interfaceNumber, alternateSet ting, createBaseCallback(bind<bool>(&USBDevice::asyncSelectAlternateInterface, t his, interfaceNumber, alternateSetting, resolver)));
474 } 267 }
475 } 268 }
476 return promise; 269 return promise;
477 } 270 }
478 271
479 ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo ntrolTransferParameters& setup, unsigned length) 272 ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo ntrolTransferParameters& setup, unsigned length)
480 { 273 {
481 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 274 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
482 ScriptPromise promise = resolver->promise(); 275 ScriptPromise promise = resolver->promise();
483 if (ensureDeviceConfigured(resolver)) { 276 if (ensureDeviceConfigured(resolver)) {
484 WebUSBDevice::ControlTransferParameters parameters; 277 auto parameters = convertControlTransferParameters(setup, resolver);
485 if (convertControlTransferParameters(WebUSBDevice::TransferDirection::In , setup, &parameters, resolver)) 278 if (parameters) {
486 m_device->controlTransfer(parameters, nullptr, length, 0, new Callba ckPromiseAdapter<InputTransferResult, USBError>(resolver)); 279 m_deviceRequests.add(resolver);
280 m_device->ControlTransferIn(std::move(parameters), length, 0, create BaseCallback(bind<usb::TransferStatus, mojo::WTFArray<uint8_t>>(&USBDevice::asyn cControlTransferIn, this, resolver)));
281 }
487 } 282 }
488 return promise; 283 return promise;
489 } 284 }
490 285
491 ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC ontrolTransferParameters& setup) 286 ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC ontrolTransferParameters& setup)
492 { 287 {
493 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 288 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
494 ScriptPromise promise = resolver->promise(); 289 ScriptPromise promise = resolver->promise();
495 if (ensureDeviceConfigured(resolver)) { 290 if (ensureDeviceConfigured(resolver)) {
496 WebUSBDevice::ControlTransferParameters parameters; 291 auto parameters = convertControlTransferParameters(setup, resolver);
497 if (convertControlTransferParameters(WebUSBDevice::TransferDirection::Ou t, setup, &parameters, resolver)) 292 if (parameters) {
498 m_device->controlTransfer(parameters, nullptr, 0, 0, new CallbackPro miseAdapter<OutputTransferResult, USBError>(resolver)); 293 m_deviceRequests.add(resolver);
294 m_device->ControlTransferOut(std::move(parameters), mojo::WTFArray<u int8_t>(), 0, createBaseCallback(bind<usb::TransferStatus>(&USBDevice::asyncCont rolTransferOut, this, 0, resolver)));
295 }
499 } 296 }
500 return promise; 297 return promise;
501 } 298 }
502 299
503 ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC ontrolTransferParameters& setup, const ArrayBufferOrArrayBufferView& data) 300 ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC ontrolTransferParameters& setup, const ArrayBufferOrArrayBufferView& data)
504 { 301 {
505 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 302 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
506 ScriptPromise promise = resolver->promise(); 303 ScriptPromise promise = resolver->promise();
507 if (ensureDeviceConfigured(resolver)) { 304 if (ensureDeviceConfigured(resolver)) {
508 WebUSBDevice::ControlTransferParameters parameters; 305 auto parameters = convertControlTransferParameters(setup, resolver);
509 if (convertControlTransferParameters(WebUSBDevice::TransferDirection::Ou t, setup, &parameters, resolver)) { 306 if (parameters) {
510 BufferSource buffer(data); 307 mojo::WTFArray<uint8_t> buffer = convertBufferSource(data);
511 m_device->controlTransfer(parameters, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver)); 308 unsigned transferLength = buffer.size();
309 m_deviceRequests.add(resolver);
310 m_device->ControlTransferOut(std::move(parameters), std::move(buffer ), 0, createBaseCallback(bind<usb::TransferStatus>(&USBDevice::asyncControlTrans ferOut, this, transferLength, resolver)));
512 } 311 }
513 } 312 }
514 return promise; 313 return promise;
515 } 314 }
516 315
517 ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, String direction, u int8_t endpointNumber) 316 ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, String direction, u int8_t endpointNumber)
518 { 317 {
519 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 318 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
520 ScriptPromise promise = resolver->promise(); 319 ScriptPromise promise = resolver->promise();
521 if (ensureEndpointAvailable(direction == "in", endpointNumber, resolver)) 320 if (ensureEndpointAvailable(direction == "in", endpointNumber, resolver)) {
522 m_device->clearHalt(endpointNumber, new CallbackPromiseAdapter<void, USB Error>(resolver)); 321 m_deviceRequests.add(resolver);
322 m_device->ClearHalt(endpointNumber, createBaseCallback(bind<bool>(&USBDe vice::asyncClearHalt, this, resolver)));
323 }
523 return promise; 324 return promise;
524 } 325 }
525 326
526 ScriptPromise USBDevice::transferIn(ScriptState* scriptState, uint8_t endpointNu mber, unsigned length) 327 ScriptPromise USBDevice::transferIn(ScriptState* scriptState, uint8_t endpointNu mber, unsigned length)
527 { 328 {
528 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 329 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
529 ScriptPromise promise = resolver->promise(); 330 ScriptPromise promise = resolver->promise();
530 if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver)) 331 if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver)) {
531 m_device->transfer(WebUSBDevice::TransferDirection::In, endpointNumber, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(re solver)); 332 m_deviceRequests.add(resolver);
333 m_device->GenericTransferIn(endpointNumber, length, 0, createBaseCallbac k(bind<usb::TransferStatus, mojo::WTFArray<uint8_t>>(&USBDevice::asyncTransferIn , this, resolver)));
334 }
532 return promise; 335 return promise;
533 } 336 }
534 337
535 ScriptPromise USBDevice::transferOut(ScriptState* scriptState, uint8_t endpointN umber, const ArrayBufferOrArrayBufferView& data) 338 ScriptPromise USBDevice::transferOut(ScriptState* scriptState, uint8_t endpointN umber, const ArrayBufferOrArrayBufferView& data)
536 { 339 {
537 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 340 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
538 ScriptPromise promise = resolver->promise(); 341 ScriptPromise promise = resolver->promise();
539 if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) { 342 if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) {
540 BufferSource buffer(data); 343 mojo::WTFArray<uint8_t> buffer = convertBufferSource(data);
541 m_device->transfer(WebUSBDevice::TransferDirection::Out, endpointNumber, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResul t, USBError>(resolver)); 344 unsigned transferLength = buffer.size();
345 m_deviceRequests.add(resolver);
346 m_device->GenericTransferOut(endpointNumber, std::move(buffer), 0, creat eBaseCallback(bind<usb::TransferStatus>(&USBDevice::asyncTransferOut, this, tran sferLength, resolver)));
542 } 347 }
543 return promise; 348 return promise;
544 } 349 }
545 350
546 ScriptPromise USBDevice::isochronousTransferIn(ScriptState* scriptState, uint8_t endpointNumber, Vector<unsigned> packetLengths) 351 ScriptPromise USBDevice::isochronousTransferIn(ScriptState* scriptState, uint8_t endpointNumber, Vector<unsigned> packetLengths)
547 { 352 {
548 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 353 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
549 ScriptPromise promise = resolver->promise(); 354 ScriptPromise promise = resolver->promise();
550 if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver)) 355 if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver)) {
551 m_device->isochronousTransfer(WebUSBDevice::TransferDirection::In, endpo intNumber, nullptr, 0, packetLengths, 0, new CallbackPromiseAdapter<IsochronousI nputTransferResult, USBError>(resolver)); 356 m_deviceRequests.add(resolver);
357 m_device->IsochronousTransferIn(endpointNumber, mojo::WTFArray<uint32_t> (std::move(packetLengths)), 0, createBaseCallback(bind<mojo::WTFArray<uint8_t>, mojo::WTFArray<usb::IsochronousPacketPtr>>(&USBDevice::asyncIsochronousTransferI n, this, resolver)));
358 }
552 return promise; 359 return promise;
553 } 360 }
554 361
555 ScriptPromise USBDevice::isochronousTransferOut(ScriptState* scriptState, uint8_ t endpointNumber, const ArrayBufferOrArrayBufferView& data, Vector<unsigned> pac ketLengths) 362 ScriptPromise USBDevice::isochronousTransferOut(ScriptState* scriptState, uint8_ t endpointNumber, const ArrayBufferOrArrayBufferView& data, Vector<unsigned> pac ketLengths)
556 { 363 {
557 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 364 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
558 ScriptPromise promise = resolver->promise(); 365 ScriptPromise promise = resolver->promise();
559 if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) { 366 if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) {
560 BufferSource buffer(data); 367 m_deviceRequests.add(resolver);
561 m_device->isochronousTransfer(WebUSBDevice::TransferDirection::Out, endp ointNumber, buffer.data(), buffer.size(), packetLengths, 0, new CallbackPromiseA dapter<IsochronousOutputTransferResult, USBError>(resolver)); 368 m_device->IsochronousTransferOut(endpointNumber, convertBufferSource(dat a), mojo::WTFArray<uint32_t>(std::move(packetLengths)), 0, createBaseCallback(bi nd<mojo::WTFArray<usb::IsochronousPacketPtr>>(&USBDevice::asyncIsochronousTransf erOut, this, resolver)));
562 } 369 }
563 return promise; 370 return promise;
564 } 371 }
565 372
566 ScriptPromise USBDevice::reset(ScriptState* scriptState) 373 ScriptPromise USBDevice::reset(ScriptState* scriptState)
567 { 374 {
568 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 375 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
569 ScriptPromise promise = resolver->promise(); 376 ScriptPromise promise = resolver->promise();
570 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) { 377 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
571 if (!m_opened) 378 if (!m_opened) {
572 resolver->reject(DOMException::create(InvalidStateError, kOpenRequir ed)); 379 resolver->reject(DOMException::create(InvalidStateError, kOpenRequir ed));
573 else 380 } else {
574 m_device->reset(new CallbackPromiseAdapter<void, USBError>(resolver) ); 381 m_deviceRequests.add(resolver);
382 m_device->Reset(createBaseCallback(bind<bool>(&USBDevice::asyncReset , this, resolver)));
383 }
575 } 384 }
576 return promise; 385 return promise;
577 } 386 }
578 387
579 void USBDevice::contextDestroyed() 388 void USBDevice::contextDestroyed()
580 { 389 {
581 if (m_opened) { 390 m_device.reset();
582 m_device->close(new WebUSBDeviceCloseCallbacks()); 391 m_deviceRequests.clear();
583 m_opened = false;
584 }
585 } 392 }
586 393
587 DEFINE_TRACE(USBDevice) 394 DEFINE_TRACE(USBDevice)
588 { 395 {
589 ContextLifecycleObserver::trace(visitor); 396 ContextLifecycleObserver::trace(visitor);
397 visitor->trace(m_deviceRequests);
590 } 398 }
591 399
592 int USBDevice::findConfigurationIndex(uint8_t configurationValue) const 400 int USBDevice::findConfigurationIndex(uint8_t configurationValue) const
593 { 401 {
594 const auto& configurations = info().configurations; 402 const auto& configurations = info().configurations;
595 for (size_t i = 0; i < configurations.size(); ++i) { 403 for (size_t i = 0; i < configurations.size(); ++i) {
596 if (configurations[i].configurationValue == configurationValue) 404 if (configurations[i]->configuration_value == configurationValue)
597 return i; 405 return i;
598 } 406 }
599 return -1; 407 return -1;
600 } 408 }
601 409
602 int USBDevice::findInterfaceIndex(uint8_t interfaceNumber) const 410 int USBDevice::findInterfaceIndex(uint8_t interfaceNumber) const
603 { 411 {
604 ASSERT(m_configurationIndex != -1); 412 ASSERT(m_configurationIndex != -1);
605 const auto& interfaces = info().configurations[m_configurationIndex].interfa ces; 413 const auto& interfaces = info().configurations[m_configurationIndex]->interf aces;
606 for (size_t i = 0; i < interfaces.size(); ++i) { 414 for (size_t i = 0; i < interfaces.size(); ++i) {
607 if (interfaces[i].interfaceNumber == interfaceNumber) 415 if (interfaces[i]->interface_number == interfaceNumber)
608 return i; 416 return i;
609 } 417 }
610 return -1; 418 return -1;
611 } 419 }
612 420
613 int USBDevice::findAlternateIndex(size_t interfaceIndex, uint8_t alternateSettin g) const 421 int USBDevice::findAlternateIndex(size_t interfaceIndex, uint8_t alternateSettin g) const
614 { 422 {
615 ASSERT(m_configurationIndex != -1); 423 ASSERT(m_configurationIndex != -1);
616 const auto& alternates = info().configurations[m_configurationIndex].interfa ces[interfaceIndex].alternates; 424 const auto& alternates = info().configurations[m_configurationIndex]->interf aces[interfaceIndex]->alternates;
617 for (size_t i = 0; i < alternates.size(); ++i) { 425 for (size_t i = 0; i < alternates.size(); ++i) {
618 if (alternates[i].alternateSetting == alternateSetting) 426 if (alternates[i]->alternate_setting == alternateSetting)
619 return i; 427 return i;
620 } 428 }
621 return -1; 429 return -1;
622 } 430 }
623 431
624 bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver* resolver) const 432 bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver* resolver) const
625 { 433 {
626 if (m_deviceStateChangeInProgress) 434 if (!m_device)
435 resolver->reject(DOMException::create(NotFoundError, kDeviceUnavailable) );
436 else if (m_deviceStateChangeInProgress)
627 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); 437 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress));
628 else if (anyInterfaceChangeInProgress()) 438 else if (anyInterfaceChangeInProgress())
629 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress)); 439 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress));
630 else 440 else
631 return true; 441 return true;
632 return false; 442 return false;
633 } 443 }
634 444
635 bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const 445 bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const
636 { 446 {
637 if (m_deviceStateChangeInProgress) 447 if (!m_device)
448 resolver->reject(DOMException::create(NotFoundError, kDeviceUnavailable) );
449 else if (m_deviceStateChangeInProgress)
638 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); 450 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress));
639 else if (!m_opened) 451 else if (!m_opened)
640 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ; 452 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ;
641 else if (m_configurationIndex == -1) 453 else if (m_configurationIndex == -1)
642 resolver->reject(DOMException::create(InvalidStateError, "The device mus t have a configuration selected.")); 454 resolver->reject(DOMException::create(InvalidStateError, "The device mus t have a configuration selected."));
643 else 455 else
644 return true; 456 return true;
645 return false; 457 return false;
646 } 458 }
647 459
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 491
680 bool USBDevice::anyInterfaceChangeInProgress() const 492 bool USBDevice::anyInterfaceChangeInProgress() const
681 { 493 {
682 for (size_t i = 0; i < m_interfaceStateChangeInProgress.size(); ++i) { 494 for (size_t i = 0; i < m_interfaceStateChangeInProgress.size(); ++i) {
683 if (m_interfaceStateChangeInProgress.quickGet(i)) 495 if (m_interfaceStateChangeInProgress.quickGet(i))
684 return true; 496 return true;
685 } 497 }
686 return false; 498 return false;
687 } 499 }
688 500
689 bool USBDevice::convertControlTransferParameters( 501 usb::ControlTransferParamsPtr USBDevice::convertControlTransferParameters(
690 WebUSBDevice::TransferDirection direction,
691 const USBControlTransferParameters& parameters, 502 const USBControlTransferParameters& parameters,
692 WebUSBDevice::ControlTransferParameters* webParameters,
693 ScriptPromiseResolver* resolver) const 503 ScriptPromiseResolver* resolver) const
694 { 504 {
695 webParameters->direction = direction; 505 auto mojoParameters = usb::ControlTransferParams::New();
696 506
697 if (parameters.requestType() == "standard") { 507 if (parameters.requestType() == "standard") {
698 webParameters->type = WebUSBDevice::RequestType::Standard; 508 mojoParameters->type = usb::ControlTransferType::STANDARD;
699 } else if (parameters.requestType() == "class") { 509 } else if (parameters.requestType() == "class") {
700 webParameters->type = WebUSBDevice::RequestType::Class; 510 mojoParameters->type = usb::ControlTransferType::CLASS;
701 } else if (parameters.requestType() == "vendor") { 511 } else if (parameters.requestType() == "vendor") {
702 webParameters->type = WebUSBDevice::RequestType::Vendor; 512 mojoParameters->type = usb::ControlTransferType::VENDOR;
703 } else { 513 } else {
704 resolver->reject(DOMException::create(TypeMismatchError, "The control tr ansfer requestType parameter is invalid.")); 514 resolver->reject(DOMException::create(TypeMismatchError, "The control tr ansfer requestType parameter is invalid."));
705 return false; 515 return nullptr;
706 } 516 }
707 517
708 if (parameters.recipient() == "device") { 518 if (parameters.recipient() == "device") {
709 webParameters->recipient = WebUSBDevice::RequestRecipient::Device; 519 mojoParameters->recipient = usb::ControlTransferRecipient::DEVICE;
710 } else if (parameters.recipient() == "interface") { 520 } else if (parameters.recipient() == "interface") {
711 size_t interfaceNumber = parameters.index() & 0xff; 521 size_t interfaceNumber = parameters.index() & 0xff;
712 if (!ensureInterfaceClaimed(interfaceNumber, resolver)) 522 if (!ensureInterfaceClaimed(interfaceNumber, resolver))
713 return false; 523 return nullptr;
714 webParameters->recipient = WebUSBDevice::RequestRecipient::Interface; 524 mojoParameters->recipient = usb::ControlTransferRecipient::INTERFACE;
715 } else if (parameters.recipient() == "endpoint") { 525 } else if (parameters.recipient() == "endpoint") {
716 bool inTransfer = parameters.index() & 0x80; 526 bool inTransfer = parameters.index() & 0x80;
717 size_t endpointNumber = parameters.index() & 0x0f; 527 size_t endpointNumber = parameters.index() & 0x0f;
718 if (!ensureEndpointAvailable(inTransfer, endpointNumber, resolver)) 528 if (!ensureEndpointAvailable(inTransfer, endpointNumber, resolver))
719 return false; 529 return nullptr;
720 webParameters->recipient = WebUSBDevice::RequestRecipient::Endpoint; 530 mojoParameters->recipient = usb::ControlTransferRecipient::ENDPOINT;
721 } else if (parameters.recipient() == "other") { 531 } else if (parameters.recipient() == "other") {
722 webParameters->recipient = WebUSBDevice::RequestRecipient::Other; 532 mojoParameters->recipient = usb::ControlTransferRecipient::OTHER;
723 } else { 533 } else {
724 resolver->reject(DOMException::create(TypeMismatchError, "The control tr ansfer recipient parameter is invalid.")); 534 resolver->reject(DOMException::create(TypeMismatchError, "The control tr ansfer recipient parameter is invalid."));
725 return false; 535 return nullptr;
726 } 536 }
727 537
728 webParameters->request = parameters.request(); 538 mojoParameters->request = parameters.request();
729 webParameters->value = parameters.value(); 539 mojoParameters->value = parameters.value();
730 webParameters->index = parameters.index(); 540 mojoParameters->index = parameters.index();
731 return true; 541 return mojoParameters;
732 } 542 }
733 543
734 void USBDevice::setEndpointsForInterface(size_t interfaceIndex, bool set) 544 void USBDevice::setEndpointsForInterface(size_t interfaceIndex, bool set)
735 { 545 {
736 const auto& configuration = info().configurations[m_configurationIndex]; 546 const auto& configuration = *info().configurations[m_configurationIndex];
737 const auto& interface = configuration.interfaces[interfaceIndex]; 547 const auto& interface = *configuration.interfaces[interfaceIndex];
738 const auto& alternate = interface.alternates[m_selectedAlternates[interfaceI ndex]]; 548 const auto& alternate = *interface.alternates[m_selectedAlternates[interface Index]];
739 for (const auto& endpoint : alternate.endpoints) { 549 for (const auto& endpoint : alternate.endpoints.storage()) {
740 if (endpoint.endpointNumber == 0 || endpoint.endpointNumber >= 16) 550 uint8_t endpointNumber = endpoint->endpoint_number;
551 if (endpointNumber == 0 || endpointNumber >= 16)
741 continue; // Ignore endpoints with invalid indices. 552 continue; // Ignore endpoints with invalid indices.
742 auto& bitVector = endpoint.direction == WebUSBDevice::TransferDirection: :In ? m_inEndpoints : m_outEndpoints; 553 auto& bitVector = endpoint->direction == usb::TransferDirection::INBOUND ? m_inEndpoints : m_outEndpoints;
743 if (set) 554 if (set)
744 bitVector.set(endpoint.endpointNumber - 1); 555 bitVector.set(endpointNumber - 1);
745 else 556 else
746 bitVector.clear(endpoint.endpointNumber - 1); 557 bitVector.clear(endpointNumber - 1);
747 } 558 }
559 }
560
561 void USBDevice::asyncOpen(ScriptPromiseResolver* resolver, usb::OpenDeviceError error)
562 {
563 m_deviceRequests.remove(resolver);
564 if (!isActive(resolver))
565 return;
566
567 switch (error) {
568 case usb::OpenDeviceError::ALREADY_OPEN:
569 ASSERT_NOT_REACHED();
570 // fall through
571 case usb::OpenDeviceError::OK:
572 onDeviceOpenedOrClosed(true /* opened */);
573 resolver->resolve();
574 return;
575 case usb::OpenDeviceError::ACCESS_DENIED:
576 onDeviceOpenedOrClosed(false /* not opened */);
577 resolver->reject(DOMException::create(SecurityError, "Access denied."));
578 return;
579 }
580 }
581
582 void USBDevice::asyncClose(ScriptPromiseResolver* resolver)
583 {
584 m_deviceRequests.remove(resolver);
585 if (!isActive(resolver))
586 return;
587
588 onDeviceOpenedOrClosed(false /* closed */);
589 resolver->resolve();
590 }
591
592 void USBDevice::onDeviceOpenedOrClosed(bool opened)
593 {
594 m_opened = opened;
595 m_deviceStateChangeInProgress = false;
596 }
597
598 void USBDevice::asyncSelectConfiguration(size_t configurationIndex, ScriptPromis eResolver* resolver, bool success)
599 {
600 m_deviceRequests.remove(resolver);
601 if (!isActive(resolver))
602 return;
603
604 onConfigurationSelected(success, configurationIndex);
605 if (success)
606 resolver->resolve();
607 else
608 resolver->reject(DOMException::create(NetworkError, "Unable to set devic e configuration."));
609 }
610
611 void USBDevice::onConfigurationSelected(bool success, size_t configurationIndex)
612 {
613 if (success) {
614 m_configurationIndex = configurationIndex;
615 size_t numInterfaces = info().configurations[m_configurationIndex]->inte rfaces.size();
616 m_claimedInterfaces.clearAll();
617 m_claimedInterfaces.resize(numInterfaces);
618 m_interfaceStateChangeInProgress.clearAll();
619 m_interfaceStateChangeInProgress.resize(numInterfaces);
620 m_selectedAlternates.resize(numInterfaces);
621 m_selectedAlternates.fill(0);
622 m_inEndpoints.clearAll();
623 m_outEndpoints.clearAll();
624 }
625 m_deviceStateChangeInProgress = false;
626 }
627
628 void USBDevice::asyncClaimInterface(size_t interfaceIndex, ScriptPromiseResolver * resolver, bool success)
629 {
630 m_deviceRequests.remove(resolver);
631 if (!isActive(resolver))
632 return;
633
634 onInterfaceClaimedOrUnclaimed(success, interfaceIndex);
635 if (success)
636 resolver->resolve();
637 else
638 resolver->reject(DOMException::create(NetworkError, "Unable to claim int erface."));
639 }
640
641 void USBDevice::asyncReleaseInterface(size_t interfaceIndex, ScriptPromiseResolv er* resolver, bool success)
642 {
643 m_deviceRequests.remove(resolver);
644 if (!isActive(resolver))
645 return;
646
647 onInterfaceClaimedOrUnclaimed(!success, interfaceIndex);
648 if (success)
649 resolver->resolve();
650 else
651 resolver->reject(DOMException::create(NetworkError, "Unable to release i nterface."));
652 }
653
654 void USBDevice::onInterfaceClaimedOrUnclaimed(bool claimed, size_t interfaceInde x)
655 {
656 if (claimed) {
657 m_claimedInterfaces.set(interfaceIndex);
658 } else {
659 m_claimedInterfaces.clear(interfaceIndex);
660 m_selectedAlternates[interfaceIndex] = 0;
661 }
662 setEndpointsForInterface(interfaceIndex, claimed);
663 m_interfaceStateChangeInProgress.clear(interfaceIndex);
664 }
665
666 void USBDevice::asyncSelectAlternateInterface(size_t interfaceIndex, size_t alte rnateIndex, ScriptPromiseResolver* resolver, bool success)
667 {
668 m_deviceRequests.remove(resolver);
669 if (!isActive(resolver))
670 return;
671
672 if (success)
673 m_selectedAlternates[interfaceIndex] = alternateIndex;
674 setEndpointsForInterface(interfaceIndex, success);
675 m_interfaceStateChangeInProgress.clear(interfaceIndex);
676
677 if (success)
678 resolver->resolve();
679 else
680 resolver->reject(DOMException::create(NetworkError, "Unable to set devic e interface."));
681 }
682
683 void USBDevice::asyncControlTransferIn(ScriptPromiseResolver* resolver, usb::Tra nsferStatus status, mojo::WTFArray<uint8_t> data)
684 {
685 m_deviceRequests.remove(resolver);
686 if (!isActive(resolver))
687 return;
688
689 DOMException* error = convertFatalTransferStatus(status);
690 if (error)
691 resolver->reject(error);
692 else
693 resolver->resolve(USBInTransferResult::create(convertTransferStatus(stat us), data.PassStorage()));
694 }
695
696 void USBDevice::asyncControlTransferOut(unsigned transferLength, ScriptPromiseRe solver* resolver, usb::TransferStatus status)
697 {
698 m_deviceRequests.remove(resolver);
699 if (!isActive(resolver))
700 return;
701
702 DOMException* error = convertFatalTransferStatus(status);
703 if (error)
704 resolver->reject(error);
705 else
706 resolver->resolve(USBOutTransferResult::create(convertTransferStatus(sta tus), transferLength));
707 }
708
709 void USBDevice::asyncClearHalt(ScriptPromiseResolver* resolver, bool success)
710 {
711 m_deviceRequests.remove(resolver);
712 if (!isActive(resolver))
713 return;
714
715 if (success)
716 resolver->resolve();
717 else
718 resolver->reject(DOMException::create(NetworkError, "Unable to clear end point."));
719 }
720
721 void USBDevice::asyncTransferIn(ScriptPromiseResolver* resolver, usb::TransferSt atus status, mojo::WTFArray<uint8_t> data)
722 {
723 m_deviceRequests.remove(resolver);
724 if (!isActive(resolver))
725 return;
726
727 DOMException* error = convertFatalTransferStatus(status);
728 if (error)
729 resolver->reject(error);
730 else
731 resolver->resolve(USBInTransferResult::create(convertTransferStatus(stat us), data.PassStorage()));
732 }
733
734 void USBDevice::asyncTransferOut(unsigned transferLength, ScriptPromiseResolver* resolver, usb::TransferStatus status)
735 {
736 m_deviceRequests.remove(resolver);
737 if (!isActive(resolver))
738 return;
739
740 DOMException* error = convertFatalTransferStatus(status);
741 if (error)
742 resolver->reject(error);
743 else
744 resolver->resolve(USBOutTransferResult::create(convertTransferStatus(sta tus), transferLength));
745 }
746
747 void USBDevice::asyncIsochronousTransferIn(ScriptPromiseResolver* resolver, mojo ::WTFArray<uint8_t> data, mojo::WTFArray<usb::IsochronousPacketPtr> mojoPackets)
748 {
749 m_deviceRequests.remove(resolver);
750 if (!isActive(resolver))
751 return;
752
753 DOMArrayBuffer* buffer = DOMArrayBuffer::create(data.storage().data(), data. storage().size());
754 HeapVector<Member<USBIsochronousInTransferPacket>> packets;
755 packets.reserveCapacity(mojoPackets.size());
756 size_t byteOffset = 0;
757 for (const auto& packet : mojoPackets.storage()) {
758 DOMException* error = convertFatalTransferStatus(packet->status);
759 if (error) {
760 resolver->reject(error);
761 return;
762 }
763 packets.append(USBIsochronousInTransferPacket::create(convertTransferSta tus(packet->status), DOMDataView::create(buffer, byteOffset, packet->transferred _length)));
764 byteOffset += packet->length;
765 }
766 resolver->resolve(USBIsochronousInTransferResult::create(buffer, packets));
767 }
768
769 void USBDevice::asyncIsochronousTransferOut(ScriptPromiseResolver* resolver, moj o::WTFArray<usb::IsochronousPacketPtr> mojoPackets)
770 {
771 m_deviceRequests.remove(resolver);
772 if (!isActive(resolver))
773 return;
774
775 HeapVector<Member<USBIsochronousOutTransferPacket>> packets;
776 packets.reserveCapacity(mojoPackets.size());
777 for (const auto& packet : mojoPackets.storage()) {
778 DOMException* error = convertFatalTransferStatus(packet->status);
779 if (error) {
780 resolver->reject(error);
781 return;
782 }
783 packets.append(USBIsochronousOutTransferPacket::create(convertTransferSt atus(packet->status), packet->transferred_length));
784 }
785 resolver->resolve(USBIsochronousOutTransferResult::create(packets));
786 }
787
788 void USBDevice::asyncReset(ScriptPromiseResolver* resolver, bool success)
789 {
790 m_deviceRequests.remove(resolver);
791 if (!isActive(resolver))
792 return;
793
794 if (success)
795 resolver->resolve();
796 else
797 resolver->reject(DOMException::create(NetworkError, "Unable to reset the device."));
748 } 798 }
749 799
750 } // namespace blink 800 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/webusb/USBDevice.h ('k') | third_party/WebKit/Source/modules/webusb/USBEndpoint.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698