OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "modules/webusb/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 Loading... | |
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, ¶meters, 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, ¶meters, 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, ¶meters, 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 Loading... | |
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 |
OLD | NEW |