Chromium Code Reviews| 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/CallbackPromiseAdapter.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" | 17 #include "modules/webusb/USBError.h" |
| 18 #include "modules/webusb/USBInTransferResult.h" | 18 #include "modules/webusb/USBInTransferResult.h" |
| 19 #include "modules/webusb/USBIsochronousInTransferResult.h" | 19 #include "modules/webusb/USBIsochronousInTransferResult.h" |
| 20 #include "modules/webusb/USBIsochronousOutTransferResult.h" | 20 #include "modules/webusb/USBIsochronousOutTransferResult.h" |
| 21 #include "modules/webusb/USBOutTransferResult.h" | 21 #include "modules/webusb/USBOutTransferResult.h" |
| 22 #include "public/platform/modules/webusb/WebUSBTransferInfo.h" | 22 #include "public/platform/modules/webusb/WebUSBTransferInfo.h" |
| 23 #include "wtf/Assertions.h" | 23 #include "wtf/Assertions.h" |
| 24 | 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 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."; | |
| 30 const char kOpenRequired[] = "The device must be opened first."; | 32 const char kOpenRequired[] = "The device must be opened first."; |
| 31 | 33 |
| 32 DOMException* convertControlTransferParameters( | 34 DOMException* convertControlTransferParameters( |
| 33 WebUSBDevice::TransferDirection direction, | 35 WebUSBDevice::TransferDirection direction, |
| 34 const USBControlTransferParameters& parameters, | 36 const USBControlTransferParameters& parameters, |
| 35 WebUSBDevice::ControlTransferParameters* webParameters) | 37 WebUSBDevice::ControlTransferParameters* webParameters) |
| 36 { | 38 { |
| 37 webParameters->direction = direction; | 39 webParameters->direction = direction; |
| 38 | 40 |
| 39 if (parameters.requestType() == "standard") | 41 if (parameters.requestType() == "standard") |
| 40 webParameters->type = WebUSBDevice::RequestType::Standard; | 42 webParameters->type = WebUSBDevice::RequestType::Standard; |
| 41 else if (parameters.requestType() == "class") | 43 else if (parameters.requestType() == "class") |
| 42 webParameters->type = WebUSBDevice::RequestType::Class; | 44 webParameters->type = WebUSBDevice::RequestType::Class; |
| 43 else if (parameters.requestType() == "vendor") | 45 else if (parameters.requestType() == "vendor") |
| 44 webParameters->type = WebUSBDevice::RequestType::Vendor; | 46 webParameters->type = WebUSBDevice::RequestType::Vendor; |
| 45 else | 47 else |
| 46 return DOMException::create(TypeMismatchError, "The control transfer req uestType parameter is invalid."); | 48 return DOMException::create(TypeMismatchError, "The control transfer req uestType parameter is invalid."); |
| 47 | 49 |
| 50 // TODO(reillyg): Check for interface and endpoint availability if that is | |
| 51 // the control transfer target. | |
| 48 if (parameters.recipient() == "device") | 52 if (parameters.recipient() == "device") |
| 49 webParameters->recipient = WebUSBDevice::RequestRecipient::Device; | 53 webParameters->recipient = WebUSBDevice::RequestRecipient::Device; |
| 50 else if (parameters.recipient() == "interface") | 54 else if (parameters.recipient() == "interface") |
| 51 webParameters->recipient = WebUSBDevice::RequestRecipient::Interface; | 55 webParameters->recipient = WebUSBDevice::RequestRecipient::Interface; |
| 52 else if (parameters.recipient() == "endpoint") | 56 else if (parameters.recipient() == "endpoint") |
| 53 webParameters->recipient = WebUSBDevice::RequestRecipient::Endpoint; | 57 webParameters->recipient = WebUSBDevice::RequestRecipient::Endpoint; |
| 54 else if (parameters.recipient() == "other") | 58 else if (parameters.recipient() == "other") |
| 55 webParameters->recipient = WebUSBDevice::RequestRecipient::Other; | 59 webParameters->recipient = WebUSBDevice::RequestRecipient::Other; |
| 56 else | 60 else |
| 57 return DOMException::create(TypeMismatchError, "The control transfer rec ipient parameter is invalid."); | 61 return DOMException::create(TypeMismatchError, "The control transfer rec ipient parameter is invalid."); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 83 : m_device(device) | 87 : m_device(device) |
| 84 , m_resolver(resolver) | 88 , m_resolver(resolver) |
| 85 , m_desiredState(desiredState) | 89 , m_desiredState(desiredState) |
| 86 { | 90 { |
| 87 } | 91 } |
| 88 | 92 |
| 89 void onSuccess() override | 93 void onSuccess() override |
| 90 { | 94 { |
| 91 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) | 95 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) |
| 92 return; | 96 return; |
| 93 if (m_device) | 97 m_device->onDeviceOpenedOrClosed(m_desiredState); |
| 94 m_device->onDeviceOpenedOrClosed(m_desiredState); | |
| 95 m_resolver->resolve(); | 98 m_resolver->resolve(); |
| 96 } | 99 } |
| 97 | 100 |
| 98 void onError(const WebUSBError& e) override | 101 void onError(const WebUSBError& e) override |
| 99 { | 102 { |
| 100 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) | 103 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) |
| 101 return; | 104 return; |
| 102 if (m_device) | 105 m_device->onDeviceOpenedOrClosed(!m_desiredState); |
| 103 m_device->onDeviceOpenedOrClosed(!m_desiredState); | |
| 104 m_resolver->reject(USBError::take(m_resolver, e)); | 106 m_resolver->reject(USBError::take(m_resolver, e)); |
| 105 } | 107 } |
| 106 | 108 |
| 107 private: | 109 private: |
| 108 WeakPersistent<USBDevice> m_device; | 110 Persistent<USBDevice> m_device; |
| 109 Persistent<ScriptPromiseResolver> m_resolver; | 111 Persistent<ScriptPromiseResolver> m_resolver; |
| 110 bool m_desiredState; // true: open, false: closed | 112 bool m_desiredState; // true: open, false: closed |
| 111 }; | 113 }; |
| 112 | 114 |
| 113 class SelectConfigurationPromiseAdapter : public WebCallbacks<void, const WebUSB Error&> { | 115 class SelectConfigurationPromiseAdapter : public WebCallbacks<void, const WebUSB Error&> { |
| 114 public: | 116 public: |
| 115 SelectConfigurationPromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, int configurationIndex) | 117 SelectConfigurationPromiseAdapter(USBDevice* device, ScriptPromiseResolver* resolver, int configurationIndex) |
| 116 : m_device(device) | 118 : m_device(device) |
| 117 , m_resolver(resolver) | 119 , m_resolver(resolver) |
| 118 , m_configurationIndex(configurationIndex) | 120 , m_configurationIndex(configurationIndex) |
| 119 { | 121 { |
| 120 } | 122 } |
| 121 | 123 |
| 122 void onSuccess() override | 124 void onSuccess() override |
| 123 { | 125 { |
| 124 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) | 126 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) |
| 125 return; | 127 return; |
| 126 if (m_device) | 128 m_device->onConfigurationSelected(true /* success */, m_configurationInd ex); |
| 127 m_device->onConfigurationSelected(true /* success */, m_configuratio nIndex); | |
| 128 m_resolver->resolve(); | 129 m_resolver->resolve(); |
| 129 } | 130 } |
| 130 | 131 |
| 131 void onError(const WebUSBError& e) override | 132 void onError(const WebUSBError& e) override |
| 132 { | 133 { |
| 133 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) | 134 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) |
| 134 return; | 135 return; |
| 135 if (m_device) | 136 m_device->onConfigurationSelected(false /* failure */, m_configurationIn dex); |
| 136 m_device->onConfigurationSelected(false /* failure */, m_configurati onIndex); | |
| 137 m_resolver->reject(USBError::take(m_resolver, e)); | 137 m_resolver->reject(USBError::take(m_resolver, e)); |
| 138 } | 138 } |
| 139 | 139 |
| 140 private: | 140 private: |
| 141 WeakPersistent<USBDevice> m_device; | 141 Persistent<USBDevice> m_device; |
| 142 Persistent<ScriptPromiseResolver> m_resolver; | 142 Persistent<ScriptPromiseResolver> m_resolver; |
| 143 int m_configurationIndex; | 143 int m_configurationIndex; |
| 144 }; | 144 }; |
| 145 | 145 |
| 146 class ClaimInterfacePromiseAdapter : public WebCallbacks<void, const WebUSBError &> { | |
|
juncai
2016/03/17 01:21:11
Is class ClaimInterfacePromiseAdapter used anywher
juncai
2016/03/17 05:59:34
ah, please ignore this comment. I just realized th
Reilly Grant (use Gerrit)
2016/03/17 17:07:01
It is used in claimInterface and releaseInterface.
| |
| 147 public: | |
| 148 ClaimInterfacePromiseAdapter(USBDevice* device, ScriptPromiseResolver* resol ver, int interfaceIndex, bool desiredState) | |
| 149 : m_device(device) | |
| 150 , m_resolver(resolver) | |
| 151 , m_interfaceIndex(interfaceIndex) | |
| 152 , m_desiredState(desiredState) | |
| 153 { | |
| 154 } | |
| 155 | |
| 156 void onSuccess() override | |
| 157 { | |
| 158 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) | |
| 159 return; | |
| 160 m_device->onInterfaceClaimedOrUnclaimed(m_desiredState, m_interfaceIndex ); | |
| 161 m_resolver->resolve(); | |
| 162 } | |
| 163 | |
| 164 void onError(const WebUSBError& e) override | |
| 165 { | |
| 166 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) | |
| 167 return; | |
| 168 m_device->onInterfaceClaimedOrUnclaimed(!m_desiredState, m_interfaceInde x); | |
| 169 m_resolver->reject(USBError::take(m_resolver, e)); | |
| 170 } | |
| 171 | |
| 172 private: | |
| 173 Persistent<USBDevice> m_device; | |
| 174 Persistent<ScriptPromiseResolver> m_resolver; | |
| 175 int m_interfaceIndex; | |
| 176 bool m_desiredState; // true: claimed, false: unclaimed | |
| 177 }; | |
| 178 | |
| 146 class InputTransferResult { | 179 class InputTransferResult { |
| 147 WTF_MAKE_NONCOPYABLE(InputTransferResult); | 180 WTF_MAKE_NONCOPYABLE(InputTransferResult); |
| 148 public: | 181 public: |
| 149 using WebType = OwnPtr<WebUSBTransferInfo>; | 182 using WebType = OwnPtr<WebUSBTransferInfo>; |
| 150 | 183 |
| 151 static USBInTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTr ansferInfo> webTransferInfo) | 184 static USBInTransferResult* take(ScriptPromiseResolver*, PassOwnPtr<WebUSBTr ansferInfo> webTransferInfo) |
| 152 { | 185 { |
| 153 ASSERT(webTransferInfo->status.size() == 1); | 186 ASSERT(webTransferInfo->status.size() == 1); |
| 154 return USBInTransferResult::create(convertTransferStatus(webTransferInfo ->status[0]), webTransferInfo->data); | 187 return USBInTransferResult::create(convertTransferStatus(webTransferInfo ->status[0]), webTransferInfo->data); |
| 155 } | 188 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 242 USBDevice* USBDevice::take(ScriptPromiseResolver* resolver, PassOwnPtr<WebUSBDev ice> device) | 275 USBDevice* USBDevice::take(ScriptPromiseResolver* resolver, PassOwnPtr<WebUSBDev ice> device) |
| 243 { | 276 { |
| 244 return USBDevice::create(device, resolver->getExecutionContext()); | 277 return USBDevice::create(device, resolver->getExecutionContext()); |
| 245 } | 278 } |
| 246 | 279 |
| 247 USBDevice::USBDevice(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context) | 280 USBDevice::USBDevice(PassOwnPtr<WebUSBDevice> device, ExecutionContext* context) |
| 248 : ContextLifecycleObserver(context) | 281 : ContextLifecycleObserver(context) |
| 249 , m_device(device) | 282 , m_device(device) |
| 250 , m_opened(false) | 283 , m_opened(false) |
| 251 , m_deviceStateChangeInProgress(false) | 284 , m_deviceStateChangeInProgress(false) |
| 285 , m_configurationIndex(-1) | |
| 252 { | 286 { |
| 253 m_configurationIndex = findConfigurationIndex(info().activeConfiguration); | 287 int configurationIndex = findConfigurationIndex(info().activeConfiguration); |
| 288 if (configurationIndex != -1) | |
| 289 onConfigurationSelected(true, configurationIndex); | |
|
juncai
2016/03/17 01:21:11
nit: add comment for true parameter.
Reilly Grant (use Gerrit)
2016/03/17 17:07:01
Done.
| |
| 254 } | 290 } |
| 255 | 291 |
| 256 void USBDevice::onDeviceOpenedOrClosed(bool opened) | 292 void USBDevice::onDeviceOpenedOrClosed(bool opened) |
| 257 { | 293 { |
| 258 m_opened = opened; | 294 m_opened = opened; |
| 259 m_deviceStateChangeInProgress = false; | 295 m_deviceStateChangeInProgress = false; |
| 260 } | 296 } |
| 261 | 297 |
| 262 void USBDevice::onConfigurationSelected(bool success, int configurationIndex) | 298 void USBDevice::onConfigurationSelected(bool success, int configurationIndex) |
| 263 { | 299 { |
| 264 if (success) | 300 if (success) { |
| 265 m_configurationIndex = configurationIndex; | 301 m_configurationIndex = configurationIndex; |
| 302 size_t numInterfaces = info().configurations[m_configurationIndex].inter faces.size(); | |
| 303 m_claimedInterfaces.clearAll(); | |
| 304 m_claimedInterfaces.resize(numInterfaces); | |
| 305 m_interfaceStateChangeInProgress.clearAll(); | |
| 306 m_interfaceStateChangeInProgress.resize(numInterfaces); | |
| 307 } | |
| 266 m_deviceStateChangeInProgress = false; | 308 m_deviceStateChangeInProgress = false; |
| 267 } | 309 } |
| 268 | 310 |
| 311 void USBDevice::onInterfaceClaimedOrUnclaimed(bool claimed, int interfaceIndex) | |
| 312 { | |
| 313 if (claimed) | |
| 314 m_claimedInterfaces.set(interfaceIndex); | |
| 315 else | |
| 316 m_claimedInterfaces.clear(interfaceIndex); | |
| 317 m_interfaceStateChangeInProgress.clear(interfaceIndex); | |
| 318 } | |
| 319 | |
| 320 bool USBDevice::isInterfaceClaimed(size_t configurationIndex, size_t interfaceIn dex) const | |
| 321 { | |
| 322 return m_configurationIndex != -1 && static_cast<size_t>(m_configurationInde x) == configurationIndex && m_claimedInterfaces.get(interfaceIndex); | |
| 323 } | |
| 324 | |
| 269 USBConfiguration* USBDevice::configuration() const | 325 USBConfiguration* USBDevice::configuration() const |
| 270 { | 326 { |
| 271 if (m_configurationIndex != -1) | 327 if (m_configurationIndex != -1) |
| 272 return USBConfiguration::create(this, m_configurationIndex); | 328 return USBConfiguration::create(this, m_configurationIndex); |
| 273 return nullptr; | 329 return nullptr; |
| 274 } | 330 } |
| 275 | 331 |
| 276 HeapVector<Member<USBConfiguration>> USBDevice::configurations() const | 332 HeapVector<Member<USBConfiguration>> USBDevice::configurations() const |
| 277 { | 333 { |
| 278 HeapVector<Member<USBConfiguration>> configurations; | 334 HeapVector<Member<USBConfiguration>> configurations; |
| 279 size_t numConfigurations = info().configurations.size(); | 335 size_t numConfigurations = info().configurations.size(); |
| 280 for (size_t i = 0; i < numConfigurations; ++i) | 336 for (size_t i = 0; i < numConfigurations; ++i) |
| 281 configurations.append(USBConfiguration::create(this, i)); | 337 configurations.append(USBConfiguration::create(this, i)); |
| 282 return configurations; | 338 return configurations; |
| 283 } | 339 } |
| 284 | 340 |
| 285 ScriptPromise USBDevice::open(ScriptState* scriptState) | 341 ScriptPromise USBDevice::open(ScriptState* scriptState) |
| 286 { | 342 { |
| 287 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 343 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 288 ScriptPromise promise = resolver->promise(); | 344 ScriptPromise promise = resolver->promise(); |
| 289 if (m_deviceStateChangeInProgress) { | 345 if (m_deviceStateChangeInProgress) { |
| 290 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); | 346 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); |
| 347 } else if (anyInterfaceChangeInProgress()) { | |
| 348 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress)); | |
|
juncai
2016/03/17 01:21:11
USBDevice::open, USBDevice::close and USBDevice::s
Reilly Grant (use Gerrit)
2016/03/17 17:07:01
Done.
| |
| 291 } else if (m_opened) { | 349 } else if (m_opened) { |
| 292 resolver->resolve(); | 350 resolver->resolve(); |
| 293 } else { | 351 } else { |
| 294 m_deviceStateChangeInProgress = true; | 352 m_deviceStateChangeInProgress = true; |
| 295 m_device->open(new OpenClosePromiseAdapter(this, resolver, true /* open */)); | 353 m_device->open(new OpenClosePromiseAdapter(this, resolver, true /* open */)); |
| 296 } | 354 } |
| 297 return promise; | 355 return promise; |
| 298 } | 356 } |
| 299 | 357 |
| 300 ScriptPromise USBDevice::close(ScriptState* scriptState) | 358 ScriptPromise USBDevice::close(ScriptState* scriptState) |
| 301 { | 359 { |
| 302 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 360 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 303 ScriptPromise promise = resolver->promise(); | 361 ScriptPromise promise = resolver->promise(); |
| 304 if (m_deviceStateChangeInProgress) { | 362 if (m_deviceStateChangeInProgress) { |
| 305 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); | 363 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); |
| 364 } else if (anyInterfaceChangeInProgress()) { | |
| 365 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress)); | |
| 306 } else if (!m_opened) { | 366 } else if (!m_opened) { |
| 307 resolver->resolve(); | 367 resolver->resolve(); |
| 308 } else { | 368 } else { |
| 309 m_deviceStateChangeInProgress = true; | 369 m_deviceStateChangeInProgress = true; |
| 310 m_device->close(new OpenClosePromiseAdapter(this, resolver, false /* clo sed */)); | 370 m_device->close(new OpenClosePromiseAdapter(this, resolver, false /* clo sed */)); |
| 311 } | 371 } |
| 312 return promise; | 372 return promise; |
| 313 } | 373 } |
| 314 | 374 |
| 315 ScriptPromise USBDevice::selectConfiguration(ScriptState* scriptState, uint8_t c onfigurationValue) | 375 ScriptPromise USBDevice::selectConfiguration(ScriptState* scriptState, uint8_t c onfigurationValue) |
| 316 { | 376 { |
| 317 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 377 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 318 ScriptPromise promise = resolver->promise(); | 378 ScriptPromise promise = resolver->promise(); |
| 319 if (!m_opened) { | 379 if (!m_opened) { |
| 320 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ; | 380 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ; |
| 321 } else if (m_deviceStateChangeInProgress) { | 381 } else if (m_deviceStateChangeInProgress) { |
| 322 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); | 382 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); |
| 383 } else if (anyInterfaceChangeInProgress()) { | |
| 384 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress)); | |
| 323 } else { | 385 } else { |
| 324 int configurationIndex = findConfigurationIndex(configurationValue); | 386 int configurationIndex = findConfigurationIndex(configurationValue); |
| 325 if (configurationIndex == -1) { | 387 if (configurationIndex == -1) { |
| 326 resolver->reject(DOMException::create(NotFoundError, "The configurat ion value provided is not supported by the device.")); | 388 resolver->reject(DOMException::create(NotFoundError, "The configurat ion value provided is not supported by the device.")); |
| 327 } else if (m_configurationIndex == configurationIndex) { | 389 } else if (m_configurationIndex == configurationIndex) { |
| 328 resolver->resolve(); | 390 resolver->resolve(); |
| 329 } else { | 391 } else { |
| 330 m_deviceStateChangeInProgress = true; | 392 m_deviceStateChangeInProgress = true; |
| 331 m_device->setConfiguration(configurationValue, new SelectConfigurati onPromiseAdapter(this, resolver, configurationIndex)); | 393 m_device->setConfiguration(configurationValue, new SelectConfigurati onPromiseAdapter(this, resolver, configurationIndex)); |
| 332 } | 394 } |
| 333 } | 395 } |
| 334 return promise; | 396 return promise; |
| 335 } | 397 } |
| 336 | 398 |
| 337 ScriptPromise USBDevice::claimInterface(ScriptState* scriptState, uint8_t interf aceNumber) | 399 ScriptPromise USBDevice::claimInterface(ScriptState* scriptState, uint8_t interf aceNumber) |
| 338 { | 400 { |
| 339 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 401 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 340 ScriptPromise promise = resolver->promise(); | 402 ScriptPromise promise = resolver->promise(); |
| 341 if (ensureDeviceConfigured(resolver)) | 403 if (ensureDeviceConfigured(resolver)) { |
| 342 m_device->claimInterface(interfaceNumber, new CallbackPromiseAdapter<voi d, USBError>(resolver)); | 404 int interfaceIndex = findInterfaceIndex(interfaceNumber); |
| 405 if (interfaceIndex == -1) { | |
| 406 resolver->reject(DOMException::create(NotFoundError, kInterfaceNotFo und)); | |
| 407 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) { | |
|
juncai
2016/03/17 01:21:11
Use static_cast<size_t>(interfaceIndex) since: get
Reilly Grant (use Gerrit)
2016/03/17 17:07:01
Done.
| |
| 408 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS tateChangeInProgress)); | |
| 409 } else if (m_claimedInterfaces.get(interfaceIndex)) { | |
| 410 resolver->resolve(); | |
| 411 } else { | |
| 412 m_interfaceStateChangeInProgress.set(interfaceIndex); | |
| 413 m_device->claimInterface(interfaceNumber, new ClaimInterfacePromiseA dapter(this, resolver, interfaceIndex, true)); | |
| 414 } | |
| 415 } | |
| 343 return promise; | 416 return promise; |
| 344 } | 417 } |
| 345 | 418 |
| 346 ScriptPromise USBDevice::releaseInterface(ScriptState* scriptState, uint8_t inte rfaceNumber) | 419 ScriptPromise USBDevice::releaseInterface(ScriptState* scriptState, uint8_t inte rfaceNumber) |
| 347 { | 420 { |
| 348 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 421 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 349 ScriptPromise promise = resolver->promise(); | 422 ScriptPromise promise = resolver->promise(); |
| 350 if (ensureDeviceConfigured(resolver)) | 423 if (ensureDeviceConfigured(resolver)) { |
| 351 m_device->releaseInterface(interfaceNumber, new CallbackPromiseAdapter<v oid, USBError>(resolver)); | 424 int interfaceIndex = findInterfaceIndex(interfaceNumber); |
| 425 if (interfaceIndex == -1) { | |
| 426 resolver->reject(DOMException::create(NotFoundError, "The interface number provided is not supported by the device in its current configuration.")); | |
| 427 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) { | |
| 428 resolver->reject(DOMException::create(InvalidStateError, kInterfaceS tateChangeInProgress)); | |
| 429 } else if (!m_claimedInterfaces.get(interfaceIndex)) { | |
| 430 resolver->resolve(); | |
| 431 } else { | |
| 432 m_interfaceStateChangeInProgress.set(interfaceIndex); | |
| 433 m_device->releaseInterface(interfaceNumber, new ClaimInterfacePromis eAdapter(this, resolver, interfaceIndex, false)); | |
| 434 } | |
| 435 } | |
| 352 return promise; | 436 return promise; |
| 353 } | 437 } |
| 354 | 438 |
| 355 ScriptPromise USBDevice::setInterface(ScriptState* scriptState, uint8_t interfac eNumber, uint8_t alternateSetting) | 439 ScriptPromise USBDevice::setInterface(ScriptState* scriptState, uint8_t interfac eNumber, uint8_t alternateSetting) |
| 356 { | 440 { |
| 357 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 441 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 358 ScriptPromise promise = resolver->promise(); | 442 ScriptPromise promise = resolver->promise(); |
| 359 if (ensureDeviceConfigured(resolver)) | 443 if (ensureInterfaceClaimed(interfaceNumber, resolver)) |
| 360 m_device->setInterface(interfaceNumber, alternateSetting, new CallbackPr omiseAdapter<void, USBError>(resolver)); | 444 m_device->setInterface(interfaceNumber, alternateSetting, new CallbackPr omiseAdapter<void, USBError>(resolver)); |
| 361 return promise; | 445 return promise; |
| 362 } | 446 } |
| 363 | 447 |
| 364 ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo ntrolTransferParameters& setup, unsigned length) | 448 ScriptPromise USBDevice::controlTransferIn(ScriptState* scriptState, const USBCo ntrolTransferParameters& setup, unsigned length) |
| 365 { | 449 { |
| 366 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 450 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 367 ScriptPromise promise = resolver->promise(); | 451 ScriptPromise promise = resolver->promise(); |
| 368 if (ensureDeviceConfigured(resolver)) { | 452 if (ensureDeviceConfigured(resolver)) { |
| 369 WebUSBDevice::ControlTransferParameters parameters; | 453 WebUSBDevice::ControlTransferParameters parameters; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 401 if (error) { | 485 if (error) { |
| 402 resolver->reject(error); | 486 resolver->reject(error); |
| 403 } else { | 487 } else { |
| 404 BufferSource buffer(data); | 488 BufferSource buffer(data); |
| 405 m_device->controlTransfer(parameters, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver)); | 489 m_device->controlTransfer(parameters, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResult, USBError>(resolver)); |
| 406 } | 490 } |
| 407 } | 491 } |
| 408 return promise; | 492 return promise; |
| 409 } | 493 } |
| 410 | 494 |
| 411 ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, uint8_t endpointNum ber) | 495 ScriptPromise USBDevice::clearHalt(ScriptState* scriptState, String direction, u int8_t endpointNumber) |
| 412 { | 496 { |
| 413 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 497 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 414 ScriptPromise promise = resolver->promise(); | 498 ScriptPromise promise = resolver->promise(); |
| 415 if (ensureDeviceConfigured(resolver)) | 499 if (ensureEndpointAvailable(direction == "in", endpointNumber, resolver)) |
| 416 m_device->clearHalt(endpointNumber, new CallbackPromiseAdapter<void, USB Error>(resolver)); | 500 m_device->clearHalt(endpointNumber, new CallbackPromiseAdapter<void, USB Error>(resolver)); |
| 417 return promise; | 501 return promise; |
| 418 } | 502 } |
| 419 | 503 |
| 420 ScriptPromise USBDevice::transferIn(ScriptState* scriptState, uint8_t endpointNu mber, unsigned length) | 504 ScriptPromise USBDevice::transferIn(ScriptState* scriptState, uint8_t endpointNu mber, unsigned length) |
| 421 { | 505 { |
| 422 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 506 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 423 ScriptPromise promise = resolver->promise(); | 507 ScriptPromise promise = resolver->promise(); |
| 424 if (ensureDeviceConfigured(resolver)) | 508 if (ensureEndpointAvailable(true, endpointNumber, resolver)) |
| 425 m_device->transfer(WebUSBDevice::TransferDirection::In, endpointNumber, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(re solver)); | 509 m_device->transfer(WebUSBDevice::TransferDirection::In, endpointNumber, nullptr, length, 0, new CallbackPromiseAdapter<InputTransferResult, USBError>(re solver)); |
| 426 return promise; | 510 return promise; |
| 427 } | 511 } |
| 428 | 512 |
| 429 ScriptPromise USBDevice::transferOut(ScriptState* scriptState, uint8_t endpointN umber, const ArrayBufferOrArrayBufferView& data) | 513 ScriptPromise USBDevice::transferOut(ScriptState* scriptState, uint8_t endpointN umber, const ArrayBufferOrArrayBufferView& data) |
| 430 { | 514 { |
| 431 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 515 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 432 ScriptPromise promise = resolver->promise(); | 516 ScriptPromise promise = resolver->promise(); |
| 433 if (ensureDeviceConfigured(resolver)) { | 517 if (ensureEndpointAvailable(false, endpointNumber, resolver)) { |
| 434 BufferSource buffer(data); | 518 BufferSource buffer(data); |
| 435 m_device->transfer(WebUSBDevice::TransferDirection::Out, endpointNumber, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResul t, USBError>(resolver)); | 519 m_device->transfer(WebUSBDevice::TransferDirection::Out, endpointNumber, buffer.data(), buffer.size(), 0, new CallbackPromiseAdapter<OutputTransferResul t, USBError>(resolver)); |
| 436 } | 520 } |
| 437 return promise; | 521 return promise; |
| 438 } | 522 } |
| 439 | 523 |
| 440 ScriptPromise USBDevice::isochronousTransferIn(ScriptState* scriptState, uint8_t endpointNumber, Vector<unsigned> packetLengths) | 524 ScriptPromise USBDevice::isochronousTransferIn(ScriptState* scriptState, uint8_t endpointNumber, Vector<unsigned> packetLengths) |
| 441 { | 525 { |
| 442 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 526 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 443 ScriptPromise promise = resolver->promise(); | 527 ScriptPromise promise = resolver->promise(); |
| 444 if (ensureDeviceConfigured(resolver)) | 528 if (ensureEndpointAvailable(true, endpointNumber, resolver)) |
| 445 m_device->isochronousTransfer(WebUSBDevice::TransferDirection::In, endpo intNumber, nullptr, 0, packetLengths, 0, new CallbackPromiseAdapter<IsochronousI nputTransferResult, USBError>(resolver)); | 529 m_device->isochronousTransfer(WebUSBDevice::TransferDirection::In, endpo intNumber, nullptr, 0, packetLengths, 0, new CallbackPromiseAdapter<IsochronousI nputTransferResult, USBError>(resolver)); |
| 446 return promise; | 530 return promise; |
| 447 } | 531 } |
| 448 | 532 |
| 449 ScriptPromise USBDevice::isochronousTransferOut(ScriptState* scriptState, uint8_ t endpointNumber, const ArrayBufferOrArrayBufferView& data, Vector<unsigned> pac ketLengths) | 533 ScriptPromise USBDevice::isochronousTransferOut(ScriptState* scriptState, uint8_ t endpointNumber, const ArrayBufferOrArrayBufferView& data, Vector<unsigned> pac ketLengths) |
| 450 { | 534 { |
| 451 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 535 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 452 ScriptPromise promise = resolver->promise(); | 536 ScriptPromise promise = resolver->promise(); |
| 453 if (ensureDeviceConfigured(resolver)) { | 537 if (ensureEndpointAvailable(false, endpointNumber, resolver)) { |
| 454 BufferSource buffer(data); | 538 BufferSource buffer(data); |
| 455 m_device->isochronousTransfer(WebUSBDevice::TransferDirection::Out, endp ointNumber, buffer.data(), buffer.size(), packetLengths, 0, new CallbackPromiseA dapter<IsochronousOutputTransferResult, USBError>(resolver)); | 539 m_device->isochronousTransfer(WebUSBDevice::TransferDirection::Out, endp ointNumber, buffer.data(), buffer.size(), packetLengths, 0, new CallbackPromiseA dapter<IsochronousOutputTransferResult, USBError>(resolver)); |
| 456 } | 540 } |
| 457 return promise; | 541 return promise; |
| 458 } | 542 } |
| 459 | 543 |
| 460 ScriptPromise USBDevice::reset(ScriptState* scriptState) | 544 ScriptPromise USBDevice::reset(ScriptState* scriptState) |
| 461 { | 545 { |
| 462 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 546 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 463 ScriptPromise promise = resolver->promise(); | 547 ScriptPromise promise = resolver->promise(); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 484 int USBDevice::findConfigurationIndex(uint8_t configurationValue) const | 568 int USBDevice::findConfigurationIndex(uint8_t configurationValue) const |
| 485 { | 569 { |
| 486 const auto& configurations = info().configurations; | 570 const auto& configurations = info().configurations; |
| 487 for (size_t i = 0; i < configurations.size(); ++i) { | 571 for (size_t i = 0; i < configurations.size(); ++i) { |
| 488 if (configurations[i].configurationValue == configurationValue) | 572 if (configurations[i].configurationValue == configurationValue) |
| 489 return i; | 573 return i; |
| 490 } | 574 } |
| 491 return -1; | 575 return -1; |
| 492 } | 576 } |
| 493 | 577 |
| 578 int USBDevice::findInterfaceIndex(uint8_t interfaceNumber) const | |
|
juncai
2016/03/17 01:21:11
This function may need to return size_t.
Reilly Grant (use Gerrit)
2016/03/17 17:07:01
It can't return -1 if it returns size_t.
| |
| 579 { | |
| 580 ASSERT(m_configurationIndex != -1); | |
| 581 const auto& interfaces = info().configurations[m_configurationIndex].interfa ces; | |
| 582 for (size_t i = 0; i < interfaces.size(); ++i) { | |
| 583 if (interfaces[i].interfaceNumber == interfaceNumber) | |
| 584 return i; | |
| 585 } | |
| 586 return -1; | |
| 587 } | |
| 588 | |
| 494 bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const | 589 bool USBDevice::ensureDeviceConfigured(ScriptPromiseResolver* resolver) const |
| 495 { | 590 { |
| 496 if (!m_opened) { | 591 if (!m_opened) { |
| 497 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ; | 592 resolver->reject(DOMException::create(InvalidStateError, kOpenRequired)) ; |
| 498 } else if (m_deviceStateChangeInProgress) { | 593 } else if (m_deviceStateChangeInProgress) { |
| 499 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); | 594 resolver->reject(DOMException::create(InvalidStateError, kDeviceStateCha ngeInProgress)); |
| 500 } else if (m_configurationIndex == -1) { | 595 } else if (m_configurationIndex == -1) { |
| 501 resolver->reject(DOMException::create(InvalidStateError, "The device mus t have a configuration selected.")); | 596 resolver->reject(DOMException::create(InvalidStateError, "The device mus t have a configuration selected.")); |
| 502 } else { | 597 } else { |
| 503 return true; | 598 return true; |
| 504 } | 599 } |
| 505 return false; | 600 return false; |
| 506 } | 601 } |
| 507 | 602 |
| 603 bool USBDevice::ensureInterfaceClaimed(uint8_t interfaceNumber, ScriptPromiseRes olver* resolver) const | |
| 604 { | |
| 605 if (!ensureDeviceConfigured(resolver)) | |
| 606 return false; | |
| 607 int interfaceIndex = findInterfaceIndex(interfaceNumber); | |
| 608 if (interfaceIndex == -1) { | |
| 609 resolver->reject(DOMException::create(NotFoundError, kInterfaceNotFound) ); | |
| 610 } else if (m_interfaceStateChangeInProgress.get(interfaceIndex)) { | |
| 611 resolver->reject(DOMException::create(InvalidStateError, kInterfaceState ChangeInProgress)); | |
| 612 } else if (!m_claimedInterfaces.get(interfaceIndex)) { | |
| 613 resolver->reject(DOMException::create(InvalidStateError, "The specified interface has not been claimed.")); | |
| 614 } else { | |
| 615 return true; | |
| 616 } | |
| 617 return false; | |
| 618 } | |
| 619 | |
| 620 bool USBDevice::ensureEndpointAvailable(bool inTransfer, uint8_t endpointNumber, ScriptPromiseResolver* resolver) const | |
| 621 { | |
| 622 // TODO(reillyg): Check endpoint availability once Blink is tracking which | |
| 623 // alternate interfaces are selected. | |
| 624 return ensureDeviceConfigured(resolver); | |
| 625 } | |
| 626 | |
| 627 bool USBDevice::anyInterfaceChangeInProgress() const | |
| 628 { | |
| 629 for (size_t i = 0; i < m_interfaceStateChangeInProgress.size(); ++i) { | |
| 630 if (m_interfaceStateChangeInProgress.quickGet(i)) | |
| 631 return true; | |
| 632 } | |
| 633 return false; | |
| 634 } | |
| 635 | |
| 508 } // namespace blink | 636 } // namespace blink |
| OLD | NEW |