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

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: Move promise adapter pattern into a header that can be shared. 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" 7 #include "bindings/core/v8/MojoPromiseAdapter.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/ExceptionCode.h" 14 #include "core/dom/ExceptionCode.h"
15 #include "modules/webusb/USBConfiguration.h" 15 #include "modules/webusb/USBConfiguration.h"
16 #include "modules/webusb/USBControlTransferParameters.h" 16 #include "modules/webusb/USBControlTransferParameters.h"
17 #include "modules/webusb/USBError.h"
18 #include "modules/webusb/USBInTransferResult.h" 17 #include "modules/webusb/USBInTransferResult.h"
19 #include "modules/webusb/USBIsochronousInTransferResult.h" 18 #include "modules/webusb/USBIsochronousInTransferResult.h"
20 #include "modules/webusb/USBIsochronousOutTransferResult.h" 19 #include "modules/webusb/USBIsochronousOutTransferResult.h"
21 #include "modules/webusb/USBOutTransferResult.h" 20 #include "modules/webusb/USBOutTransferResult.h"
22 #include "public/platform/modules/webusb/WebUSBTransferInfo.h"
23 #include "wtf/Assertions.h" 21 #include "wtf/Assertions.h"
24 22
23 namespace usb = device::usb::blink;
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 .");
juncai 2016/04/15 16:52:47 This error message may be modified to better refle
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());
57 83 return mojo::WTFArray<uint8_t>(std::move(vector));
58 void onSuccess() override 84 }
59 { 85
60 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) 86 class OpenPromiseAdapter : public MojoPromiseAdapter<usb::Device::OpenCallback> {
61 return; 87 WTF_MAKE_NONCOPYABLE(OpenPromiseAdapter);
62 88
63 m_device->onDeviceOpenedOrClosed(m_desiredState); 89 public:
64 m_resolver->resolve(); 90 OpenPromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver)
65 } 91 : MojoPromiseAdapter(resolver)
66 92 , m_device(device)
67 void onError(const WebUSBError& e) override 93 {
68 { 94 }
69 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) 95
70 return; 96 ~OpenPromiseAdapter() override
71 m_device->onDeviceOpenedOrClosed(!m_desiredState); 97 {
72 m_resolver->reject(USBError::take(m_resolver, e)); 98 if (active())
73 } 99 reject(DOMException::create(NotFoundError, kDeviceUnavailable));
74 100 }
75 private: 101
76 Persistent<USBDevice> m_device; 102 void Run(usb::OpenDeviceError error) override
77 Persistent<ScriptPromiseResolver> m_resolver; 103 {
78 bool m_desiredState; // true: open, false: closed 104 if (active()) {
79 }; 105 switch (error) {
80 106 case usb::OpenDeviceError::ALREADY_OPEN:
81 class SelectConfigurationPromiseAdapter : public WebCallbacks<void, const WebUSB Error&> { 107 ASSERT_NOT_REACHED();
108 // fall through
109 case usb::OpenDeviceError::OK:
110 m_device->onDeviceOpenedOrClosed(true);
juncai 2016/04/15 16:52:47 nit: add comment for true parameter.
111 resolve();
112 break;
juncai 2016/04/15 16:52:47 can just use return; here.
113 case usb::OpenDeviceError::ACCESS_DENIED:
114 m_device->onDeviceOpenedOrClosed(false);
juncai 2016/04/15 16:52:47 nit: add comment for false parameter.
115 reject(DOMException::create(SecurityError, "Access denied."));
116 break;
juncai 2016/04/15 16:52:47 can just use return; here.
117 }
118 }
119 }
120
121 private:
122 Persistent<USBDevice> m_device;
123 };
124
125 class ClosePromiseAdapter : public MojoPromiseAdapter<usb::Device::CloseCallback > {
126 WTF_MAKE_NONCOPYABLE(ClosePromiseAdapter);
127
128 public:
129 ClosePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver)
130 : MojoPromiseAdapter(resolver)
131 , m_device(device)
132 {
133 }
134
135 ~ClosePromiseAdapter() override
136 {
137 if (active())
138 reject(DOMException::create(NotFoundError, kDeviceUnavailable));
139 }
140
141 void Run() override
142 {
143 if (active()) {
144 m_device->onDeviceOpenedOrClosed(false);
145 resolve();
146 }
147 }
148
149 private:
150 Persistent<USBDevice> m_device;
151 };
152
153 class SelectConfigurationPromiseAdapter : public MojoPromiseAdapter<usb::Device: :SetConfigurationCallback> {
154 WTF_MAKE_NONCOPYABLE(SelectConfigurationPromiseAdapter);
155
82 public: 156 public:
83 SelectConfigurationPromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, size_t configurationIndex) 157 SelectConfigurationPromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, size_t configurationIndex)
84 : m_device(device) 158 : MojoPromiseAdapter(resolver)
85 , m_resolver(resolver) 159 , m_device(device)
86 , m_configurationIndex(configurationIndex) 160 , m_configurationIndex(configurationIndex)
87 { 161 {
88 } 162 }
89 163
90 void onSuccess() override 164 ~SelectConfigurationPromiseAdapter() override
91 { 165 {
92 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) 166 if (active())
93 return; 167 reject(DOMException::create(NotFoundError, kDeviceUnavailable));
94 m_device->onConfigurationSelected(true /* success */, m_configurationInd ex); 168 }
95 m_resolver->resolve(); 169
96 } 170 void Run(bool success) override
97 171 {
98 void onError(const WebUSBError& e) override 172 if (active()) {
99 { 173 m_device->onConfigurationSelected(success, m_configurationIndex);
100 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) 174 if (success)
101 return; 175 resolve();
102 m_device->onConfigurationSelected(false /* failure */, m_configurationIn dex); 176 else
103 m_resolver->reject(USBError::take(m_resolver, e)); 177 reject(DOMException::create(NetworkError, "Unable to set device configuration."));
104 } 178 }
105 179 }
106 private: 180
107 Persistent<USBDevice> m_device; 181 private:
108 Persistent<ScriptPromiseResolver> m_resolver; 182 Persistent<USBDevice> m_device;
109 size_t m_configurationIndex; 183 size_t m_configurationIndex;
110 }; 184 };
111 185
112 class ClaimInterfacePromiseAdapter : public WebCallbacks<void, const WebUSBError &> { 186 class ClaimInterfacePromiseAdapter : public MojoPromiseAdapter<usb::Device::Clai mInterfaceCallback> {
113 public: 187 WTF_MAKE_NONCOPYABLE(ClaimInterfacePromiseAdapter);
114 ClaimInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resol ver, size_t interfaceIndex, bool desiredState) 188
115 : m_device(device) 189 public:
116 , m_resolver(resolver) 190 ClaimInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resol ver, size_t interfaceIndex)
191 : MojoPromiseAdapter(resolver)
192 , m_device(device)
117 , m_interfaceIndex(interfaceIndex) 193 , m_interfaceIndex(interfaceIndex)
118 , m_desiredState(desiredState) 194 {
119 { 195 }
120 } 196
121 197 ~ClaimInterfacePromiseAdapter() override
122 void onSuccess() override 198 {
123 { 199 if (active())
124 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) 200 reject(DOMException::create(NotFoundError, kDeviceUnavailable));
125 return; 201 }
126 m_device->onInterfaceClaimedOrUnclaimed(m_desiredState, m_interfaceIndex ); 202
127 m_resolver->resolve(); 203 void Run(bool success) override
128 } 204 {
129 205 if (active()) {
130 void onError(const WebUSBError& e) override 206 m_device->onInterfaceClaimedOrUnclaimed(success, m_interfaceIndex);
131 { 207 if (success)
132 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) 208 resolve();
133 return; 209 else
134 m_device->onInterfaceClaimedOrUnclaimed(!m_desiredState, m_interfaceInde x); 210 reject(DOMException::create(NetworkError, "Unable to claim inter face."));
135 m_resolver->reject(USBError::take(m_resolver, e)); 211 }
136 } 212 }
137 213
138 private: 214 private:
139 Persistent<USBDevice> m_device; 215 Persistent<USBDevice> m_device;
140 Persistent<ScriptPromiseResolver> m_resolver;
141 size_t m_interfaceIndex; 216 size_t m_interfaceIndex;
142 bool m_desiredState; // true: claimed, false: unclaimed 217 };
143 }; 218
144 219 class ReleaseInterfacePromiseAdapter : public MojoPromiseAdapter<usb::Device::Re leaseInterfaceCallback> {
145 class SelectAlternateInterfacePromiseAdapter : public WebCallbacks<void, const W ebUSBError&> { 220 WTF_MAKE_NONCOPYABLE(ReleaseInterfacePromiseAdapter);
146 public: 221
147 SelectAlternateInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResol ver* resolver, size_t interfaceIndex, size_t alternateIndex) 222 public:
148 : m_device(device) 223 ReleaseInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResolver* res olver, size_t interfaceIndex)
149 , m_resolver(resolver) 224 : MojoPromiseAdapter(resolver)
225 , m_device(device)
226 , m_interfaceIndex(interfaceIndex)
227 {
228 }
229
230 ~ReleaseInterfacePromiseAdapter() override
231 {
232 if (active())
233 reject(DOMException::create(NotFoundError, kDeviceUnavailable));
234 }
235
236 void Run(bool success) override
237 {
238 if (active()) {
239 m_device->onInterfaceClaimedOrUnclaimed(!success, m_interfaceIndex);
240 if (success)
241 resolve();
242 else
243 reject(DOMException::create(NetworkError, "Unable to release int erface."));
244 }
245 }
246
247 private:
248 Persistent<USBDevice> m_device;
249 size_t m_interfaceIndex;
250 };
251
252 class SetInterfacePromiseAdapter : public MojoPromiseAdapter<usb::Device::SetInt erfaceAlternateSettingCallback> {
253 WTF_MAKE_NONCOPYABLE(SetInterfacePromiseAdapter);
254
255 public:
256 SetInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolve r, size_t interfaceIndex, size_t alternateIndex)
257 : MojoPromiseAdapter(resolver)
258 , m_device(device)
150 , m_interfaceIndex(interfaceIndex) 259 , m_interfaceIndex(interfaceIndex)
151 , m_alternateIndex(alternateIndex) 260 , m_alternateIndex(alternateIndex)
152 { 261 {
153 } 262 }
154 263
155 void onSuccess() override 264 ~SetInterfacePromiseAdapter() override
156 { 265 {
157 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) 266 if (active())
158 return; 267 reject(DOMException::create(NotFoundError, kDeviceUnavailable));
159 m_device->onAlternateInterfaceSelected(true /* success */, m_interfaceIn dex, m_alternateIndex); 268 }
160 m_resolver->resolve(); 269
161 } 270 void Run(bool success) override
162 271 {
163 void onError(const WebUSBError& e) override 272 if (active()) {
164 { 273 m_device->onAlternateInterfaceSelected(success, m_interfaceIndex, m_ alternateIndex);
165 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) 274 if (success)
166 return; 275 resolve();
167 m_device->onAlternateInterfaceSelected(false /* failure */, m_interfaceI ndex, m_alternateIndex); 276 else
168 m_resolver->reject(USBError::take(m_resolver, e)); 277 reject(DOMException::create(NetworkError, "Unable to set device interface."));
169 } 278 }
170 279 }
171 private: 280
172 Persistent<USBDevice> m_device; 281 private:
173 Persistent<ScriptPromiseResolver> m_resolver; 282 Persistent<USBDevice> m_device;
174 size_t m_interfaceIndex; 283 size_t m_interfaceIndex;
175 size_t m_alternateIndex; 284 size_t m_alternateIndex;
176 }; 285 };
177 286
178 class InputTransferResult { 287 class ControlTransferInPromiseAdapter : public MojoPromiseAdapter<usb::Device::C ontrolTransferInCallback> {
179 WTF_MAKE_NONCOPYABLE(InputTransferResult); 288 WTF_MAKE_NONCOPYABLE(ControlTransferInPromiseAdapter);
180 public: 289
181 using WebType = OwnPtr<WebUSBTransferInfo>; 290 public:
182 291 ControlTransferInPromiseAdapter(ScriptPromiseResolver* resolver)
183 static USBInTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTr ansferInfo> webTransferInfo) 292 : MojoPromiseAdapter(resolver)
184 { 293 {
185 ASSERT(webTransferInfo->status.size() == 1); 294 }
186 return USBInTransferResult::create(convertTransferStatus(webTransferInfo ->status[0]), webTransferInfo->data); 295
187 } 296 ~ControlTransferInPromiseAdapter() override
188 297 {
189 private: 298 if (active())
190 InputTransferResult() = delete; 299 reject(DOMException::create(NotFoundError, kDeviceUnavailable));
191 }; 300 }
192 301
193 class OutputTransferResult { 302 void Run(usb::TransferStatus status, mojo::WTFArray<uint8_t> data) override
194 WTF_MAKE_NONCOPYABLE(OutputTransferResult); 303 {
195 public: 304 if (active()) {
196 using WebType = OwnPtr<WebUSBTransferInfo>; 305 DOMException* error = convertFatalTransferStatus(status);
197 306 if (error)
198 static USBOutTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBT ransferInfo> webTransferInfo) 307 reject(error);
199 { 308 else
200 ASSERT(webTransferInfo->status.size() == 1); 309 resolve(USBInTransferResult::create(convertTransferStatus(status ), data.PassStorage()));
201 ASSERT(webTransferInfo->bytesTransferred.size() == 1); 310 }
202 return USBOutTransferResult::create(convertTransferStatus(webTransferInf o->status[0]), webTransferInfo->bytesTransferred[0]); 311 }
203 } 312 };
204 313
205 private: 314 class ControlTransferOutPromiseAdapter : public MojoPromiseAdapter<usb::Device:: ControlTransferOutCallback> {
206 OutputTransferResult() = delete; 315 WTF_MAKE_NONCOPYABLE(ControlTransferOutPromiseAdapter);
207 }; 316
208 317 public:
209 class IsochronousInputTransferResult { 318 ControlTransferOutPromiseAdapter(ScriptPromiseResolver* resolver, unsigned t ransferLength)
210 WTF_MAKE_NONCOPYABLE(IsochronousInputTransferResult); 319 : MojoPromiseAdapter(resolver)
211 320 , m_transferLength(transferLength)
212 public: 321 {
213 using WebType = OwnPtr<WebUSBTransferInfo>; 322 }
214 323
215 static USBIsochronousInTransferResult* take(ScriptPromiseResolver*, PassOwnP tr<WebUSBTransferInfo> webTransferInfo) 324 ~ControlTransferOutPromiseAdapter() override
216 { 325 {
217 ASSERT(webTransferInfo->status.size() == webTransferInfo->packetLength.s ize() && webTransferInfo->packetLength.size() == webTransferInfo->bytesTransferr ed.size()); 326 if (active())
218 DOMArrayBuffer* buffer = DOMArrayBuffer::create(webTransferInfo->data.da ta(), webTransferInfo->data.size()); 327 reject(DOMException::create(NotFoundError, kDeviceUnavailable));
219 HeapVector<Member<USBIsochronousInTransferPacket>> packets(webTransferIn fo->status.size()); 328 }
329
330 void Run(usb::TransferStatus status) override
331 {
332 if (active()) {
333 DOMException* error = convertFatalTransferStatus(status);
334 if (error)
335 reject(error);
336 else
337 resolve(USBOutTransferResult::create(convertTransferStatus(statu s), m_transferLength));
338 }
339 }
340
341 private:
342 unsigned m_transferLength;
343 };
344
345 class ClearHaltPromiseAdapter : public MojoPromiseAdapter<usb::Device::ClearHalt Callback> {
346 WTF_MAKE_NONCOPYABLE(ClearHaltPromiseAdapter);
347
348 public:
349 ClearHaltPromiseAdapter(ScriptPromiseResolver* resolver)
350 : MojoPromiseAdapter(resolver)
351 {
352 }
353
354 ~ClearHaltPromiseAdapter() override
355 {
356 if (active())
357 reject(DOMException::create(NotFoundError, kDeviceUnavailable));
358 }
359
360 void Run(bool success) override
361 {
362 if (active()) {
363 if (success)
364 resolve();
365 else
366 reject(DOMException::create(NetworkError, "Unable to clear endpo int."));
367 }
368 }
369 };
370
371 class GenericTransferInPromiseAdapter : public MojoPromiseAdapter<usb::Device::G enericTransferInCallback> {
372 WTF_MAKE_NONCOPYABLE(GenericTransferInPromiseAdapter);
373
374 public:
375 GenericTransferInPromiseAdapter(ScriptPromiseResolver* resolver)
376 : MojoPromiseAdapter(resolver)
377 {
378 }
379
380 ~GenericTransferInPromiseAdapter() override
381 {
382 if (active())
383 reject(DOMException::create(NotFoundError, kDeviceUnavailable));
384 }
385
386 void Run(usb::TransferStatus status, mojo::WTFArray<uint8_t> data) override
387 {
388 if (active()) {
389 DOMException* error = convertFatalTransferStatus(status);
390 if (error)
391 reject(error);
392 else
393 resolve(USBInTransferResult::create(convertTransferStatus(status ), data.PassStorage()));
394 }
395 }
396 };
397
398 class GenericTransferOutPromiseAdapter : public MojoPromiseAdapter<usb::Device:: GenericTransferOutCallback> {
399 WTF_MAKE_NONCOPYABLE(GenericTransferOutPromiseAdapter);
400
401 public:
402 GenericTransferOutPromiseAdapter(ScriptPromiseResolver* resolver, unsigned t ransferLength)
403 : MojoPromiseAdapter(resolver)
404 , m_transferLength(transferLength)
405 {
406 }
407
408 ~GenericTransferOutPromiseAdapter() override
409 {
410 if (active())
411 reject(DOMException::create(NotFoundError, kDeviceUnavailable));
412 }
413
414 void Run(usb::TransferStatus status) override
415 {
416 if (active()) {
417 DOMException* error = convertFatalTransferStatus(status);
418 if (error)
419 reject(error);
420 else
421 resolve(USBOutTransferResult::create(convertTransferStatus(statu s), m_transferLength));
422 }
423 }
424
425 private:
426 unsigned m_transferLength;
427 };
428
429 class IsochronousTransferInPromiseAdapter : public MojoPromiseAdapter<usb::Devic e::IsochronousTransferInCallback> {
430 WTF_MAKE_NONCOPYABLE(IsochronousTransferInPromiseAdapter);
431
432 public:
433 IsochronousTransferInPromiseAdapter(ScriptPromiseResolver* resolver)
434 : MojoPromiseAdapter(resolver)
435 {
436 }
437
438 ~IsochronousTransferInPromiseAdapter() override
439 {
440 if (active())
441 reject(DOMException::create(NotFoundError, kDeviceUnavailable));
442 }
443
444 void Run(mojo::WTFArray<uint8_t> data, mojo::WTFArray<usb::IsochronousPacket Ptr> mojoPackets) override
445 {
446 DOMArrayBuffer* buffer = DOMArrayBuffer::create(data.storage().data(), d ata.storage().size());
447 HeapVector<Member<USBIsochronousInTransferPacket>> packets;
448 packets.reserveCapacity(mojoPackets.size());
220 size_t byteOffset = 0; 449 size_t byteOffset = 0;
221 for (size_t i = 0; i < webTransferInfo->status.size(); ++i) { 450 for (const auto& packet : mojoPackets.storage()) {
222 packets[i] = USBIsochronousInTransferPacket::create(convertTransferS tatus(webTransferInfo->status[i]), DOMDataView::create(buffer, byteOffset, webTr ansferInfo->bytesTransferred[i])); 451 DOMException* error = convertFatalTransferStatus(packet->status);
223 byteOffset += webTransferInfo->packetLength[i]; 452 if (error) {
224 } 453 reject(error);
225 return USBIsochronousInTransferResult::create(buffer, packets); 454 return;
226 } 455 }
227 }; 456 packets.append(USBIsochronousInTransferPacket::create(convertTransfe rStatus(packet->status), DOMDataView::create(buffer, byteOffset, packet->transfe rred_length)));
228 457 byteOffset += packet->length;
229 class IsochronousOutputTransferResult { 458 }
230 WTF_MAKE_NONCOPYABLE(IsochronousOutputTransferResult); 459 resolve(USBIsochronousInTransferResult::create(buffer, packets));
231 460 }
232 public: 461 };
233 using WebType = OwnPtr<WebUSBTransferInfo>; 462
234 463 class IsochronousTransferOutPromiseAdapter : public MojoPromiseAdapter<usb::Devi ce::IsochronousTransferOutCallback> {
235 static USBIsochronousOutTransferResult* take(ScriptPromiseResolver*, PassOwn Ptr<WebUSBTransferInfo> webTransferInfo) 464 WTF_MAKE_NONCOPYABLE(IsochronousTransferOutPromiseAdapter);
236 { 465
237 ASSERT(webTransferInfo->status.size() == webTransferInfo->bytesTransferr ed.size()); 466 public:
238 HeapVector<Member<USBIsochronousOutTransferPacket>> packets(webTransferI nfo->status.size()); 467 IsochronousTransferOutPromiseAdapter(ScriptPromiseResolver* resolver)
239 for (size_t i = 0; i < webTransferInfo->status.size(); ++i) 468 : MojoPromiseAdapter(resolver)
240 packets[i] = USBIsochronousOutTransferPacket::create(convertTransfer Status(webTransferInfo->status[i]), webTransferInfo->bytesTransferred[i]); 469 {
241 return USBIsochronousOutTransferResult::create(packets); 470 }
242 } 471
243 }; 472 ~IsochronousTransferOutPromiseAdapter() override
244 473 {
245 class BufferSource { 474 if (active())
246 WTF_MAKE_NONCOPYABLE(BufferSource); 475 reject(DOMException::create(NotFoundError, kDeviceUnavailable));
247 public: 476 }
248 BufferSource(const ArrayBufferOrArrayBufferView& buffer) : m_buffer(buffer) 477
249 { 478 void Run(mojo::WTFArray<usb::IsochronousPacketPtr> mojoPackets) override
250 ASSERT(!m_buffer.isNull()); 479 {
251 } 480 HeapVector<Member<USBIsochronousOutTransferPacket>> packets;
252 481 packets.reserveCapacity(mojoPackets.size());
253 uint8_t* data() const 482 for (const auto& packet : mojoPackets.storage()) {
254 { 483 DOMException* error = convertFatalTransferStatus(packet->status);
255 if (m_buffer.isArrayBuffer()) 484 if (error) {
256 return static_cast<uint8_t*>(m_buffer.getAsArrayBuffer()->data()); 485 reject(error);
257 return static_cast<uint8_t*>(m_buffer.getAsArrayBufferView()->baseAddres s()); 486 return;
258 } 487 }
259 488 packets.append(USBIsochronousOutTransferPacket::create(convertTransf erStatus(packet->status), packet->transferred_length));
260 unsigned size() const 489 }
261 { 490 resolve(USBIsochronousOutTransferResult::create(packets));
262 if (m_buffer.isArrayBuffer()) 491 }
263 return m_buffer.getAsArrayBuffer()->byteLength(); 492 };
264 return m_buffer.getAsArrayBufferView()->byteLength(); 493
265 } 494 class ResetPromiseAdapter : public MojoPromiseAdapter<usb::Device::ResetCallback > {
266 495 WTF_MAKE_NONCOPYABLE(ResetPromiseAdapter);
267 private: 496
268 const ArrayBufferOrArrayBufferView& m_buffer; 497 public:
498 ResetPromiseAdapter(ScriptPromiseResolver* resolver)
499 : MojoPromiseAdapter(resolver)
500 {
501 }
502
503 ~ResetPromiseAdapter() override
504 {
505 if (active())
506 reject(DOMException::create(NotFoundError, kDeviceUnavailable));
507 }
508
509 void Run(bool success) override
510 {
511 if (active()) {
512 if (success)
513 resolve();
514 else
515 reject(DOMException::create(NetworkError, "Unable to reset the d evice."));
516 }
517 }
269 }; 518 };
270 519
271 } // namespace 520 } // namespace
272 521
273 // static 522 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) 523 : ContextLifecycleObserver(context)
281 , m_device(device) 524 , m_deviceInfo(std::move(deviceInfo))
525 , m_device(std::move(device))
282 , m_opened(false) 526 , m_opened(false)
283 , m_deviceStateChangeInProgress(false) 527 , m_deviceStateChangeInProgress(false)
284 , m_configurationIndex(-1) 528 , m_configurationIndex(-1)
285 , m_inEndpoints(15)
286 , m_outEndpoints(15)
287 { 529 {
288 int configurationIndex = findConfigurationIndex(info().activeConfiguration); 530 if (m_device) {
531 m_device.set_connection_error_handler([this]() {
532 m_device = nullptr;
533 m_opened = false;
534 });
535 }
536 int configurationIndex = findConfigurationIndex(info().active_configuration) ;
289 if (configurationIndex != -1) 537 if (configurationIndex != -1)
290 onConfigurationSelected(true /* success */, configurationIndex); 538 onConfigurationSelected(true /* success */, configurationIndex);
291 } 539 }
292 540
541 USBDevice::~USBDevice()
542 {
543 }
544
293 void USBDevice::onDeviceOpenedOrClosed(bool opened) 545 void USBDevice::onDeviceOpenedOrClosed(bool opened)
294 { 546 {
295 m_opened = opened; 547 m_opened = opened;
296 m_deviceStateChangeInProgress = false; 548 m_deviceStateChangeInProgress = false;
297 } 549 }
298 550
299 void USBDevice::onConfigurationSelected(bool success, size_t configurationIndex) 551 void USBDevice::onConfigurationSelected(bool success, size_t configurationIndex)
300 { 552 {
301 if (success) { 553 if (success) {
302 m_configurationIndex = configurationIndex; 554 m_configurationIndex = configurationIndex;
303 size_t numInterfaces = info().configurations[m_configurationIndex].inter faces.size(); 555 size_t numInterfaces = info().configurations[m_configurationIndex]->inte rfaces.size();
304 m_claimedInterfaces.clearAll(); 556 m_claimedInterfaces.clearAll();
305 m_claimedInterfaces.resize(numInterfaces); 557 m_claimedInterfaces.resize(numInterfaces);
306 m_interfaceStateChangeInProgress.clearAll(); 558 m_interfaceStateChangeInProgress.clearAll();
307 m_interfaceStateChangeInProgress.resize(numInterfaces); 559 m_interfaceStateChangeInProgress.resize(numInterfaces);
308 m_selectedAlternates.resize(numInterfaces); 560 m_selectedAlternates.resize(numInterfaces);
309 m_selectedAlternates.fill(0); 561 m_selectedAlternates.fill(0);
310 m_inEndpoints.clearAll(); 562 m_inEndpoints.clearAll();
311 m_outEndpoints.clearAll(); 563 m_outEndpoints.clearAll();
312 } 564 }
313 m_deviceStateChangeInProgress = false; 565 m_deviceStateChangeInProgress = false;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 597
346 USBConfiguration* USBDevice::configuration() const 598 USBConfiguration* USBDevice::configuration() const
347 { 599 {
348 if (m_configurationIndex != -1) 600 if (m_configurationIndex != -1)
349 return USBConfiguration::create(this, m_configurationIndex); 601 return USBConfiguration::create(this, m_configurationIndex);
350 return nullptr; 602 return nullptr;
351 } 603 }
352 604
353 HeapVector<Member<USBConfiguration>> USBDevice::configurations() const 605 HeapVector<Member<USBConfiguration>> USBDevice::configurations() const
354 { 606 {
355 HeapVector<Member<USBConfiguration>> configurations;
356 size_t numConfigurations = info().configurations.size(); 607 size_t numConfigurations = info().configurations.size();
608 HeapVector<Member<USBConfiguration>> configurations(numConfigurations);
357 for (size_t i = 0; i < numConfigurations; ++i) 609 for (size_t i = 0; i < numConfigurations; ++i)
358 configurations.append(USBConfiguration::create(this, i)); 610 configurations[i] = USBConfiguration::create(this, i);
359 return configurations; 611 return configurations;
360 } 612 }
361 613
362 ScriptPromise USBDevice::open(ScriptState* scriptState) 614 ScriptPromise USBDevice::open(ScriptState* scriptState)
363 { 615 {
364 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 616 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
365 ScriptPromise promise = resolver->promise(); 617 ScriptPromise promise = resolver->promise();
366 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) { 618 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
367 if (m_opened) { 619 if (m_opened) {
368 resolver->resolve(); 620 resolver->resolve();
369 } else { 621 } else {
370 m_deviceStateChangeInProgress = true; 622 m_deviceStateChangeInProgress = true;
371 m_device->open(new OpenClosePromiseAdapter(this, resolver, true /* o pen */)); 623 auto adapter = new OpenPromiseAdapter(this, resolver);
624 m_device->Open(adapter->callback());
372 } 625 }
373 } 626 }
374 return promise; 627 return promise;
375 } 628 }
376 629
377 ScriptPromise USBDevice::close(ScriptState* scriptState) 630 ScriptPromise USBDevice::close(ScriptState* scriptState)
378 { 631 {
379 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 632 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
380 ScriptPromise promise = resolver->promise(); 633 ScriptPromise promise = resolver->promise();
381 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) { 634 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
382 if (!m_opened) { 635 if (!m_opened) {
383 resolver->resolve(); 636 resolver->resolve();
384 } else { 637 } else {
385 m_deviceStateChangeInProgress = true; 638 m_deviceStateChangeInProgress = true;
386 m_device->close(new OpenClosePromiseAdapter(this, resolver, false /* closed */)); 639 auto adapter = new ClosePromiseAdapter(this, resolver);
640 m_device->Close(adapter->callback());
387 } 641 }
388 } 642 }
389 return promise; 643 return promise;
390 } 644 }
391 645
392 ScriptPromise USBDevice::selectConfiguration(ScriptState* scriptState, uint8_t c onfigurationValue) 646 ScriptPromise USBDevice::selectConfiguration(ScriptState* scriptState, uint8_t c onfigurationValue)
393 { 647 {
394 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 648 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
395 ScriptPromise promise = resolver->promise(); 649 ScriptPromise promise = resolver->promise();
396 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) { 650 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
397 if (!m_opened) { 651 if (!m_opened) {
398 resolver->reject(DOMException::create(InvalidStateError, kOpenRequir ed)); 652 resolver->reject(DOMException::create(InvalidStateError, kOpenRequir ed));
399 } else { 653 } else {
400 int configurationIndex = findConfigurationIndex(configurationValue); 654 int configurationIndex = findConfigurationIndex(configurationValue);
401 if (configurationIndex == -1) { 655 if (configurationIndex == -1) {
402 resolver->reject(DOMException::create(NotFoundError, "The config uration value provided is not supported by the device.")); 656 resolver->reject(DOMException::create(NotFoundError, "The config uration value provided is not supported by the device."));
403 } else if (m_configurationIndex == configurationIndex) { 657 } else if (m_configurationIndex == configurationIndex) {
404 resolver->resolve(); 658 resolver->resolve();
405 } else { 659 } else {
406 m_deviceStateChangeInProgress = true; 660 m_deviceStateChangeInProgress = true;
407 m_device->setConfiguration(configurationValue, new SelectConfigu rationPromiseAdapter(this, resolver, configurationIndex)); 661 auto adapter = new SelectConfigurationPromiseAdapter(this, resol ver, configurationIndex);
662 m_device->SetConfiguration(configurationValue, adapter->callback ());
408 } 663 }
409 } 664 }
410 } 665 }
411 return promise; 666 return promise;
412 } 667 }
413 668
414 ScriptPromise USBDevice::claimInterface(ScriptState* scriptState, uint8_t interf aceNumber) 669 ScriptPromise USBDevice::claimInterface(ScriptState* scriptState, uint8_t interf aceNumber)
415 { 670 {
416 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 671 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
417 ScriptPromise promise = resolver->promise(); 672 ScriptPromise promise = resolver->promise();
418 if (ensureDeviceConfigured(resolver)) { 673 if (ensureDeviceConfigured(resolver)) {
419 int interfaceIndex = findInterfaceIndex(interfaceNumber); 674 int interfaceIndex = findInterfaceIndex(interfaceNumber);
420 if (interfaceIndex == -1) { 675 if (interfaceIndex == -1) {
421 resolver->reject(DOMException::create(NotFoundError, kInterfaceNotFo und)); 676 resolver->reject(DOMException::create(NotFoundError, kInterfaceNotFo und));
422 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) { 677 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) {
423 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS tateChangeInProgress)); 678 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS tateChangeInProgress));
424 } else if (m_claimedInterfaces.get(interfaceIndex)) { 679 } else if (m_claimedInterfaces.get(interfaceIndex)) {
425 resolver->resolve(); 680 resolver->resolve();
426 } else { 681 } else {
427 m_interfaceStateChangeInProgress.set(interfaceIndex); 682 m_interfaceStateChangeInProgress.set(interfaceIndex);
428 m_device->claimInterface(interfaceNumber, new ClaimInterfacePromiseA dapter(this, resolver, interfaceIndex, true /* claim */)); 683 auto adapter = new ClaimInterfacePromiseAdapter(this, resolver, inte rfaceIndex);
684 m_device->ClaimInterface(interfaceNumber, adapter->callback());
429 } 685 }
430 } 686 }
431 return promise; 687 return promise;
432 } 688 }
433 689
434 ScriptPromise USBDevice::releaseInterface(ScriptState* scriptState, uint8_t inte rfaceNumber) 690 ScriptPromise USBDevice::releaseInterface(ScriptState* scriptState, uint8_t inte rfaceNumber)
435 { 691 {
436 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 692 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
437 ScriptPromise promise = resolver->promise(); 693 ScriptPromise promise = resolver->promise();
438 if (ensureDeviceConfigured(resolver)) { 694 if (ensureDeviceConfigured(resolver)) {
439 int interfaceIndex = findInterfaceIndex(interfaceNumber); 695 int interfaceIndex = findInterfaceIndex(interfaceNumber);
440 if (interfaceIndex == -1) { 696 if (interfaceIndex == -1) {
441 resolver->reject(DOMException::create(NotFoundError, "The interface number provided is not supported by the device in its current configuration.")); 697 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)) { 698 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) {
443 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS tateChangeInProgress)); 699 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS tateChangeInProgress));
444 } else if (!m_claimedInterfaces.get(interfaceIndex)) { 700 } else if (!m_claimedInterfaces.get(interfaceIndex)) {
445 resolver->resolve(); 701 resolver->resolve();
446 } else { 702 } else {
447 // Mark this interface's endpoints unavailable while its state is 703 // Mark this interface's endpoints unavailable while its state is
448 // changing. 704 // changing.
449 setEndpointsForInterface(interfaceIndex, false); 705 setEndpointsForInterface(interfaceIndex, false);
450 m_interfaceStateChangeInProgress.set(interfaceIndex); 706 m_interfaceStateChangeInProgress.set(interfaceIndex);
451 m_device->releaseInterface(interfaceNumber, new ClaimInterfacePromis eAdapter(this, resolver, interfaceIndex, false /* release */)); 707 auto adapter = new ReleaseInterfacePromiseAdapter(this, resolver, in terfaceIndex);
708 m_device->ReleaseInterface(interfaceNumber, adapter->callback());
452 } 709 }
453 } 710 }
454 return promise; 711 return promise;
455 } 712 }
456 713
457 ScriptPromise USBDevice::selectAlternateInterface(ScriptState* scriptState, uint 8_t interfaceNumber, uint8_t alternateSetting) 714 ScriptPromise USBDevice::selectAlternateInterface(ScriptState* scriptState, uint 8_t interfaceNumber, uint8_t alternateSetting)
458 { 715 {
459 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 716 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
460 ScriptPromise promise = resolver->promise(); 717 ScriptPromise promise = resolver->promise();
461 if (ensureInterfaceClaimed(interfaceNumber, resolver)) { 718 if (ensureInterfaceClaimed(interfaceNumber, resolver)) {
462 // TODO(reillyg): This is duplicated work. 719 // TODO(reillyg): This is duplicated work.
463 int interfaceIndex = findInterfaceIndex(interfaceNumber); 720 int interfaceIndex = findInterfaceIndex(interfaceNumber);
464 ASSERT(interfaceIndex != -1); 721 ASSERT(interfaceIndex != -1);
465 int alternateIndex = findAlternateIndex(interfaceIndex, alternateSetting ); 722 int alternateIndex = findAlternateIndex(interfaceIndex, alternateSetting );
466 if (alternateIndex == -1) { 723 if (alternateIndex == -1) {
467 resolver->reject(DOMException::create(NotFoundError, "The alternate setting provided is not supported by the device in its current configuration.")) ; 724 resolver->reject(DOMException::create(NotFoundError, "The alternate setting provided is not supported by the device in its current configuration.")) ;
468 } else { 725 } else {
469 // Mark this old alternate interface's endpoints unavailable while 726 // Mark this old alternate interface's endpoints unavailable while
470 // the change is in progress. 727 // the change is in progress.
471 setEndpointsForInterface(interfaceIndex, false); 728 setEndpointsForInterface(interfaceIndex, false);
472 m_interfaceStateChangeInProgress.set(interfaceIndex); 729 m_interfaceStateChangeInProgress.set(interfaceIndex);
473 m_device->setInterface(interfaceNumber, alternateSetting, new Select AlternateInterfacePromiseAdapter(this, resolver, interfaceIndex, alternateIndex) ); 730 auto adapter = new SetInterfacePromiseAdapter(this, resolver, interf aceIndex, alternateIndex);
731 m_device->SetInterfaceAlternateSetting(interfaceNumber, alternateSet ting, adapter->callback());
474 } 732 }
475 } 733 }
476 return promise; 734 return promise;
477 } 735 }
478 736
479 ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo ntrolTransferParameters& setup, unsigned length) 737 ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo ntrolTransferParameters& setup, unsigned length)
480 { 738 {
481 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 739 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
482 ScriptPromise promise = resolver->promise(); 740 ScriptPromise promise = resolver->promise();
483 if (ensureDeviceConfigured(resolver)) { 741 if (ensureDeviceConfigured(resolver)) {
484 WebUSBDevice::ControlTransferParameters parameters; 742 auto parameters = convertControlTransferParameters(setup, resolver);
485 if (convertControlTransferParameters(WebUSBDevice::TransferDirection::In , setup, &parameters, resolver)) 743 if (parameters) {
486 m_device->controlTransfer(parameters, nullptr, length, 0, new Callba ckPromiseAdapter<InputTransferResult, USBError>(resolver)); 744 auto adapter = new ControlTransferInPromiseAdapter(resolver);
745 m_device->ControlTransferIn(std::move(parameters), length, 0, adapte r->callback());
746 }
487 } 747 }
488 return promise; 748 return promise;
489 } 749 }
490 750
491 ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC ontrolTransferParameters& setup) 751 ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC ontrolTransferParameters& setup)
492 { 752 {
493 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 753 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
494 ScriptPromise promise = resolver->promise(); 754 ScriptPromise promise = resolver->promise();
495 if (ensureDeviceConfigured(resolver)) { 755 if (ensureDeviceConfigured(resolver)) {
496 WebUSBDevice::ControlTransferParameters parameters; 756 auto parameters = convertControlTransferParameters(setup, resolver);
497 if (convertControlTransferParameters(WebUSBDevice::TransferDirection::Ou t, setup, &parameters, resolver)) 757 if (parameters) {
498 m_device->controlTransfer(parameters, nullptr, 0, 0, new CallbackPro miseAdapter<OutputTransferResult, USBError>(resolver)); 758 auto adapter = new ControlTransferOutPromiseAdapter(resolver, 0);
759 m_device->ControlTransferOut(std::move(parameters), mojo::WTFArray<u int8_t>(), 0, adapter->callback());
760 }
499 } 761 }
500 return promise; 762 return promise;
501 } 763 }
502 764
503 ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC ontrolTransferParameters& setup, const ArrayBufferOrArrayBufferView& data) 765 ScriptPromise USBDevice::controlTransferOut(ScriptState* scriptState, const USBC ontrolTransferParameters& setup, const ArrayBufferOrArrayBufferView& data)
504 { 766 {
505 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 767 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
506 ScriptPromise promise = resolver->promise(); 768 ScriptPromise promise = resolver->promise();
507 if (ensureDeviceConfigured(resolver)) { 769 if (ensureDeviceConfigured(resolver)) {
508 WebUSBDevice::ControlTransferParameters parameters; 770 auto parameters = convertControlTransferParameters(setup, resolver);
509 if (convertControlTransferParameters(WebUSBDevice::TransferDirection::Ou t, setup, &parameters, resolver)) { 771 if (parameters) {
510 BufferSource buffer(data); 772 mojo::WTFArray<uint8_t> buffer = convertBufferSource(data);
511 m_device->controlTransfer(parameters, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver)); 773 auto adapter = new ControlTransferOutPromiseAdapter(resolver, buffer .size());
774 m_device->ControlTransferOut(std::move(parameters), std::move(buffer ), 0, adapter->callback());
512 } 775 }
513 } 776 }
514 return promise; 777 return promise;
515 } 778 }
516 779
517 ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, String direction, u int8_t endpointNumber) 780 ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, String direction, u int8_t endpointNumber)
518 { 781 {
519 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 782 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
520 ScriptPromise promise = resolver->promise(); 783 ScriptPromise promise = resolver->promise();
521 if (ensureEndpointAvailable(direction == "in", endpointNumber, resolver)) 784 if (ensureEndpointAvailable(direction == "in", endpointNumber, resolver)) {
522 m_device->clearHalt(endpointNumber, new CallbackPromiseAdapter<void, USB Error>(resolver)); 785 auto adapter = new ClearHaltPromiseAdapter(resolver);
786 m_device->ClearHalt(endpointNumber, adapter->callback());
787 }
523 return promise; 788 return promise;
524 } 789 }
525 790
526 ScriptPromise USBDevice::transferIn(ScriptState* scriptState, uint8_t endpointNu mber, unsigned length) 791 ScriptPromise USBDevice::transferIn(ScriptState* scriptState, uint8_t endpointNu mber, unsigned length)
527 { 792 {
528 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 793 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
529 ScriptPromise promise = resolver->promise(); 794 ScriptPromise promise = resolver->promise();
530 if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver)) 795 if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver)) {
531 m_device->transfer(WebUSBDevice::TransferDirection::In, endpointNumber, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(re solver)); 796 auto adapter = new GenericTransferInPromiseAdapter(resolver);
797 m_device->GenericTransferIn(endpointNumber, length, 0, adapter->callback ());
798 }
532 return promise; 799 return promise;
533 } 800 }
534 801
535 ScriptPromise USBDevice::transferOut(ScriptState* scriptState, uint8_t endpointN umber, const ArrayBufferOrArrayBufferView& data) 802 ScriptPromise USBDevice::transferOut(ScriptState* scriptState, uint8_t endpointN umber, const ArrayBufferOrArrayBufferView& data)
536 { 803 {
537 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 804 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
538 ScriptPromise promise = resolver->promise(); 805 ScriptPromise promise = resolver->promise();
539 if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) { 806 if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) {
540 BufferSource buffer(data); 807 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)); 808 auto adapter = new GenericTransferOutPromiseAdapter(resolver, buffer.siz e());
809 m_device->GenericTransferOut(endpointNumber, std::move(buffer), 0, adapt er->callback());
542 } 810 }
543 return promise; 811 return promise;
544 } 812 }
545 813
546 ScriptPromise USBDevice::isochronousTransferIn(ScriptState* scriptState, uint8_t endpointNumber, Vector<unsigned> packetLengths) 814 ScriptPromise USBDevice::isochronousTransferIn(ScriptState* scriptState, uint8_t endpointNumber, Vector<unsigned> packetLengths)
547 { 815 {
548 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 816 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
549 ScriptPromise promise = resolver->promise(); 817 ScriptPromise promise = resolver->promise();
550 if (ensureEndpointAvailable(true /* in */, endpointNumber, resolver)) 818 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)); 819 auto adapter = new IsochronousTransferInPromiseAdapter(resolver);
820 m_device->IsochronousTransferIn(endpointNumber, mojo::WTFArray<uint32_t> (std::move(packetLengths)), 0, adapter->callback());
821 }
552 return promise; 822 return promise;
553 } 823 }
554 824
555 ScriptPromise USBDevice::isochronousTransferOut(ScriptState* scriptState, uint8_ t endpointNumber, const ArrayBufferOrArrayBufferView& data, Vector<unsigned> pac ketLengths) 825 ScriptPromise USBDevice::isochronousTransferOut(ScriptState* scriptState, uint8_ t endpointNumber, const ArrayBufferOrArrayBufferView& data, Vector<unsigned> pac ketLengths)
556 { 826 {
557 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 827 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
558 ScriptPromise promise = resolver->promise(); 828 ScriptPromise promise = resolver->promise();
559 if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) { 829 if (ensureEndpointAvailable(false /* out */, endpointNumber, resolver)) {
560 BufferSource buffer(data); 830 auto adapter = new IsochronousTransferOutPromiseAdapter(resolver);
561 m_device->isochronousTransfer(WebUSBDevice::TransferDirection::Out, endp ointNumber, buffer.data(), buffer.size(), packetLengths, 0, new CallbackPromiseA dapter<IsochronousOutputTransferResult, USBError>(resolver)); 831 m_device->IsochronousTransferOut(endpointNumber, convertBufferSource(dat a), mojo::WTFArray<uint32_t>(std::move(packetLengths)), 0, adapter->callback());
562 } 832 }
563 return promise; 833 return promise;
564 } 834 }
565 835
566 ScriptPromise USBDevice::reset(ScriptState* scriptState) 836 ScriptPromise USBDevice::reset(ScriptState* scriptState)
567 { 837 {
568 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 838 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
569 ScriptPromise promise = resolver->promise(); 839 ScriptPromise promise = resolver->promise();
570 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) { 840 if (ensureNoDeviceOrInterfaceChangeInProgress(resolver)) {
571 if (!m_opened) 841 if (!m_opened) {
572 resolver->reject(DOMException::create(InvalidStateError, kOpenRequir ed)); 842 resolver->reject(DOMException::create(InvalidStateError, kOpenRequir ed));
573 else 843 } else {
574 m_device->reset(new CallbackPromiseAdapter<void, USBError>(resolver) ); 844 auto adapter = new ResetPromiseAdapter(resolver);
845 m_device->Reset(adapter->callback());
846 }
575 } 847 }
576 return promise; 848 return promise;
577 } 849 }
578 850
579 void USBDevice::contextDestroyed() 851 void USBDevice::contextDestroyed()
580 { 852 {
581 if (m_opened) { 853 m_device.reset();
582 m_device->close(new WebUSBDeviceCloseCallbacks());
583 m_opened = false;
584 }
585 } 854 }
586 855
587 DEFINE_TRACE(USBDevice) 856 DEFINE_TRACE(USBDevice)
588 { 857 {
589 ContextLifecycleObserver::trace(visitor); 858 ContextLifecycleObserver::trace(visitor);
590 } 859 }
591 860
592 int USBDevice::findConfigurationIndex(uint8_t configurationValue) const 861 int USBDevice::findConfigurationIndex(uint8_t configurationValue) const
593 { 862 {
594 const auto& configurations = info().configurations; 863 const auto& configurations = info().configurations;
595 for (size_t i = 0; i < configurations.size(); ++i) { 864 for (size_t i = 0; i < configurations.size(); ++i) {
596 if (configurations[i].configurationValue == configurationValue) 865 if (configurations[i]->configuration_value == configurationValue)
597 return i; 866 return i;
598 } 867 }
599 return -1; 868 return -1;
600 } 869 }
601 870
602 int USBDevice::findInterfaceIndex(uint8_t interfaceNumber) const 871 int USBDevice::findInterfaceIndex(uint8_t interfaceNumber) const
603 { 872 {
604 ASSERT(m_configurationIndex != -1); 873 ASSERT(m_configurationIndex != -1);
605 const auto& interfaces = info().configurations[m_configurationIndex].interfa ces; 874 const auto& interfaces = info().configurations[m_configurationIndex]->interf aces;
606 for (size_t i = 0; i < interfaces.size(); ++i) { 875 for (size_t i = 0; i < interfaces.size(); ++i) {
607 if (interfaces[i].interfaceNumber == interfaceNumber) 876 if (interfaces[i]->interface_number == interfaceNumber)
608 return i; 877 return i;
609 } 878 }
610 return -1; 879 return -1;
611 } 880 }
612 881
613 int USBDevice::findAlternateIndex(size_t interfaceIndex, uint8_t alternateSettin g) const 882 int USBDevice::findAlternateIndex(size_t interfaceIndex, uint8_t alternateSettin g) const
614 { 883 {
615 ASSERT(m_configurationIndex != -1); 884 ASSERT(m_configurationIndex != -1);
616 const auto& alternates = info().configurations[m_configurationIndex].interfa ces[interfaceIndex].alternates; 885 const auto& alternates = info().configurations[m_configurationIndex]->interf aces[interfaceIndex]->alternates;
617 for (size_t i = 0; i < alternates.size(); ++i) { 886 for (size_t i = 0; i < alternates.size(); ++i) {
618 if (alternates[i].alternateSetting == alternateSetting) 887 if (alternates[i]->alternate_setting == alternateSetting)
619 return i; 888 return i;
620 } 889 }
621 return -1; 890 return -1;
622 } 891 }
623 892
624 bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver* resolver) const 893 bool USBDevice::ensureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver* resolver) const
625 { 894 {
626 if (m_deviceStateChangeInProgress) 895 if (!m_device)
896 resolver->reject(DOMException::create(NotFoundError, kDeviceUnavailable) );
897 else if (m_deviceStateChangeInProgress)
627 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); 898 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress));
628 else if (anyInterfaceChangeInProgress()) 899 else if (anyInterfaceChangeInProgress())
629 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress)); 900 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress));
630 else 901 else
631 return true; 902 return true;
632 return false; 903 return false;
633 } 904 }
634 905
635 bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const 906 bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const
636 { 907 {
637 if (m_deviceStateChangeInProgress) 908 if (!m_device)
909 resolver->reject(DOMException::create(NotFoundError, kDeviceUnavailable) );
910 else if (m_deviceStateChangeInProgress)
638 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); 911 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress));
639 else if (!m_opened) 912 else if (!m_opened)
640 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ; 913 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ;
641 else if (m_configurationIndex == -1) 914 else if (m_configurationIndex == -1)
642 resolver->reject(DOMException::create(InvalidStateError, "The device mus t have a configuration selected.")); 915 resolver->reject(DOMException::create(InvalidStateError, "The device mus t have a configuration selected."));
643 else 916 else
644 return true; 917 return true;
645 return false; 918 return false;
646 } 919 }
647 920
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 952
680 bool USBDevice::anyInterfaceChangeInProgress() const 953 bool USBDevice::anyInterfaceChangeInProgress() const
681 { 954 {
682 for (size_t i = 0; i < m_interfaceStateChangeInProgress.size(); ++i) { 955 for (size_t i = 0; i < m_interfaceStateChangeInProgress.size(); ++i) {
683 if (m_interfaceStateChangeInProgress.quickGet(i)) 956 if (m_interfaceStateChangeInProgress.quickGet(i))
684 return true; 957 return true;
685 } 958 }
686 return false; 959 return false;
687 } 960 }
688 961
689 bool USBDevice::convertControlTransferParameters( 962 usb::ControlTransferParamsPtr USBDevice::convertControlTransferParameters(
690 WebUSBDevice::TransferDirection direction,
691 const USBControlTransferParameters& parameters, 963 const USBControlTransferParameters& parameters,
692 WebUSBDevice::ControlTransferParameters* webParameters,
693 ScriptPromiseResolver* resolver) const 964 ScriptPromiseResolver* resolver) const
694 { 965 {
695 webParameters->direction = direction; 966 auto mojoParameters = usb::ControlTransferParams::New();
696 967
697 if (parameters.requestType() == "standard") { 968 if (parameters.requestType() == "standard") {
698 webParameters->type = WebUSBDevice::RequestType::Standard; 969 mojoParameters->type = usb::ControlTransferType::STANDARD;
699 } else if (parameters.requestType() == "class") { 970 } else if (parameters.requestType() == "class") {
700 webParameters->type = WebUSBDevice::RequestType::Class; 971 mojoParameters->type = usb::ControlTransferType::CLASS;
701 } else if (parameters.requestType() == "vendor") { 972 } else if (parameters.requestType() == "vendor") {
702 webParameters->type = WebUSBDevice::RequestType::Vendor; 973 mojoParameters->type = usb::ControlTransferType::VENDOR;
703 } else { 974 } else {
704 resolver->reject(DOMException::create(TypeMismatchError, "The control tr ansfer requestType parameter is invalid.")); 975 resolver->reject(DOMException::create(TypeMismatchError, "The control tr ansfer requestType parameter is invalid."));
705 return false; 976 return nullptr;
706 } 977 }
707 978
708 if (parameters.recipient() == "device") { 979 if (parameters.recipient() == "device") {
709 webParameters->recipient = WebUSBDevice::RequestRecipient::Device; 980 mojoParameters->recipient = usb::ControlTransferRecipient::DEVICE;
710 } else if (parameters.recipient() == "interface") { 981 } else if (parameters.recipient() == "interface") {
711 size_t interfaceNumber = parameters.index() & 0xff; 982 size_t interfaceNumber = parameters.index() & 0xff;
712 if (!ensureInterfaceClaimed(interfaceNumber, resolver)) 983 if (!ensureInterfaceClaimed(interfaceNumber, resolver))
713 return false; 984 return nullptr;
714 webParameters->recipient = WebUSBDevice::RequestRecipient::Interface; 985 mojoParameters->recipient = usb::ControlTransferRecipient::INTERFACE;
715 } else if (parameters.recipient() == "endpoint") { 986 } else if (parameters.recipient() == "endpoint") {
716 bool inTransfer = parameters.index() & 0x80; 987 bool inTransfer = parameters.index() & 0x80;
717 size_t endpointNumber = parameters.index() & 0x0f; 988 size_t endpointNumber = parameters.index() & 0x0f;
718 if (!ensureEndpointAvailable(inTransfer, endpointNumber, resolver)) 989 if (!ensureEndpointAvailable(inTransfer, endpointNumber, resolver))
719 return false; 990 return nullptr;
720 webParameters->recipient = WebUSBDevice::RequestRecipient::Endpoint; 991 mojoParameters->recipient = usb::ControlTransferRecipient::ENDPOINT;
721 } else if (parameters.recipient() == "other") { 992 } else if (parameters.recipient() == "other") {
722 webParameters->recipient = WebUSBDevice::RequestRecipient::Other; 993 mojoParameters->recipient = usb::ControlTransferRecipient::OTHER;
723 } else { 994 } else {
724 resolver->reject(DOMException::create(TypeMismatchError, "The control tr ansfer recipient parameter is invalid.")); 995 resolver->reject(DOMException::create(TypeMismatchError, "The control tr ansfer recipient parameter is invalid."));
725 return false; 996 return nullptr;
726 } 997 }
727 998
728 webParameters->request = parameters.request(); 999 mojoParameters->request = parameters.request();
729 webParameters->value = parameters.value(); 1000 mojoParameters->value = parameters.value();
730 webParameters->index = parameters.index(); 1001 mojoParameters->index = parameters.index();
731 return true; 1002 return mojoParameters;
732 } 1003 }
733 1004
734 void USBDevice::setEndpointsForInterface(size_t interfaceIndex, bool set) 1005 void USBDevice::setEndpointsForInterface(size_t interfaceIndex, bool set)
735 { 1006 {
736 const auto& configuration = info().configurations[m_configurationIndex]; 1007 const auto& configuration = *info().configurations[m_configurationIndex];
737 const auto& interface = configuration.interfaces[interfaceIndex]; 1008 const auto& interface = *configuration.interfaces[interfaceIndex];
738 const auto& alternate = interface.alternates[m_selectedAlternates[interfaceI ndex]]; 1009 const auto& alternate = *interface.alternates[m_selectedAlternates[interface Index]];
739 for (const auto& endpoint : alternate.endpoints) { 1010 for (const auto& endpoint : alternate.endpoints.storage()) {
740 if (endpoint.endpointNumber == 0 || endpoint.endpointNumber >= 16) 1011 uint8_t endpointNumber = endpoint->endpoint_number;
1012 if (endpointNumber == 0 || endpointNumber >= 16)
741 continue; // Ignore endpoints with invalid indices. 1013 continue; // Ignore endpoints with invalid indices.
742 auto& bitVector = endpoint.direction == WebUSBDevice::TransferDirection: :In ? m_inEndpoints : m_outEndpoints; 1014 auto& bitVector = endpoint->direction == usb::TransferDirection::INBOUND ? m_inEndpoints : m_outEndpoints;
743 if (set) 1015 if (set)
744 bitVector.set(endpoint.endpointNumber - 1); 1016 bitVector.set(endpointNumber - 1);
745 else 1017 else
746 bitVector.clear(endpoint.endpointNumber - 1); 1018 bitVector.clear(endpointNumber - 1);
747 } 1019 }
748 } 1020 }
749 1021
750 } // namespace blink 1022 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698