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

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

Powered by Google App Engine
This is Rietveld 408576698