| OLD | NEW |
| (Empty) |
| 1 <!DOCTYPE html> | |
| 2 <script src="../resources/testharness.js"></script> | |
| 3 <script src="../resources/testharnessreport.js"></script> | |
| 4 <script src="resources/fake-devices.js"></script> | |
| 5 <script src="resources/usb-helpers.js"></script> | |
| 6 <script src="resources/webusb-test.js"></script> | |
| 7 <script> | |
| 8 'use strict'; | |
| 9 | |
| 10 function assertRejectsWithNotFoundError(promise) { | |
| 11 return assertRejectsWithError(promise, 'NotFoundError'); | |
| 12 } | |
| 13 | |
| 14 function assertRejectsWithNotOpenError(promise) { | |
| 15 return assertRejectsWithError( | |
| 16 promise, 'InvalidStateError', 'The device must be opened first.') | |
| 17 } | |
| 18 | |
| 19 function assertRejectsWithNotConfiguredError(promise) { | |
| 20 return assertRejectsWithError( | |
| 21 promise, 'InvalidStateError', | |
| 22 'The device must have a configuration selected.'); | |
| 23 } | |
| 24 | |
| 25 usb_test(() => { | |
| 26 return getFakeDevice().then(({ device, fakeDevice }) => { | |
| 27 return waitForDisconnect(fakeDevice) | |
| 28 .then(() => assertRejectsWithNotFoundError(device.open())); | |
| 29 }); | |
| 30 }, 'open rejects when called on a disconnected device'); | |
| 31 | |
| 32 usb_test(() => { | |
| 33 return getFakeDevice().then(({ device, fakeDevice }) => { | |
| 34 return device.open() | |
| 35 .then(() => waitForDisconnect(fakeDevice)) | |
| 36 .then(() => { | |
| 37 assert_false(device.opened); | |
| 38 }); | |
| 39 }); | |
| 40 }, 'disconnection closes the device'); | |
| 41 | |
| 42 usb_test(() => { | |
| 43 return getFakeDevice().then(({ device }) => { | |
| 44 assert_false(device.opened); | |
| 45 return device.open().then(() => { | |
| 46 assert_true(device.opened); | |
| 47 return device.close().then(() => { | |
| 48 assert_false(device.opened); | |
| 49 }); | |
| 50 }); | |
| 51 }); | |
| 52 }, 'a device can be opened and closed'); | |
| 53 | |
| 54 usb_test(() => { | |
| 55 return getFakeDevice().then(({ device }) => { | |
| 56 return device.open() | |
| 57 .then(() => device.open()) | |
| 58 .then(() => device.open()) | |
| 59 .then(() => device.open()) | |
| 60 .then(() => device.close()) | |
| 61 .then(() => device.close()) | |
| 62 .then(() => device.close()) | |
| 63 .then(() => device.close()); | |
| 64 }); | |
| 65 }, 'open and close can be called multiple times'); | |
| 66 | |
| 67 usb_test(() => { | |
| 68 return getFakeDevice().then(({ device }) => { | |
| 69 const message = | |
| 70 'An operation that changes the device state is in progress.'; | |
| 71 return Promise.all([ | |
| 72 device.open(), | |
| 73 assertRejectsWithError(device.open(), 'InvalidStateError', message), | |
| 74 assertRejectsWithError(device.close(), 'InvalidStateError', message), | |
| 75 ]).then(() => Promise.all([ | |
| 76 device.close(), | |
| 77 assertRejectsWithError(device.open(), 'InvalidStateError', message), | |
| 78 assertRejectsWithError(device.close(), 'InvalidStateError', message), | |
| 79 ])); | |
| 80 }); | |
| 81 }, 'open and close cannot be called again while open or close are in progress'); | |
| 82 | |
| 83 usb_test(() => { | |
| 84 return getFakeDevice().then(({ device, fakeDevice }) => { | |
| 85 return device.open() | |
| 86 .then(() => waitForDisconnect(fakeDevice)) | |
| 87 .then(() => assertRejectsWithNotFoundError(device.close())); | |
| 88 }); | |
| 89 }, 'close rejects when called on a disconnected device'); | |
| 90 | |
| 91 usb_test(() => { | |
| 92 return getFakeDevice().then(({ device, fakeDevice }) => { | |
| 93 return device.open() | |
| 94 .then(() => waitForDisconnect(fakeDevice)) | |
| 95 .then(() => assertRejectsWithNotFoundError(device.selectConfiguration(1)))
; | |
| 96 }); | |
| 97 }, 'selectConfiguration rejects when called on a disconnected device'); | |
| 98 | |
| 99 usb_test(() => { | |
| 100 return getFakeDevice().then(({ device }) => Promise.all([ | |
| 101 assertRejectsWithNotOpenError(device.selectConfiguration(1)), | |
| 102 assertRejectsWithNotOpenError(device.claimInterface(0)), | |
| 103 assertRejectsWithNotOpenError(device.releaseInterface(0)), | |
| 104 assertRejectsWithNotOpenError(device.selectAlternateInterface(0, 1)), | |
| 105 assertRejectsWithNotOpenError(device.controlTransferIn({ | |
| 106 requestType: 'vendor', | |
| 107 recipient: 'device', | |
| 108 request: 0x42, | |
| 109 value: 0x1234, | |
| 110 index: 0x5678 | |
| 111 }, 7)), | |
| 112 assertRejectsWithNotOpenError(device.controlTransferOut({ | |
| 113 requestType: 'vendor', | |
| 114 recipient: 'device', | |
| 115 request: 0x42, | |
| 116 value: 0x1234, | |
| 117 index: 0x5678 | |
| 118 }, new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]))), | |
| 119 assertRejectsWithNotOpenError(device.clearHalt('in', 1)), | |
| 120 assertRejectsWithNotOpenError(device.transferIn(1, 8)), | |
| 121 assertRejectsWithNotOpenError( | |
| 122 device.transferOut(1, new ArrayBuffer(8))), | |
| 123 assertRejectsWithNotOpenError(device.isochronousTransferIn(1, [8])), | |
| 124 assertRejectsWithNotOpenError( | |
| 125 device.isochronousTransferOut(1, new ArrayBuffer(8), [8])), | |
| 126 assertRejectsWithNotOpenError(device.reset()) | |
| 127 ])); | |
| 128 }, 'methods requiring it reject when the device is not open'); | |
| 129 | |
| 130 usb_test(() => { | |
| 131 return getFakeDevice().then(({ device }) => { | |
| 132 assert_equals(device.configuration, null); | |
| 133 return device.open() | |
| 134 .then(() => { | |
| 135 assert_equals(device.configuration, null); | |
| 136 return device.selectConfiguration(1); | |
| 137 }) | |
| 138 .then(() => { | |
| 139 assertDeviceInfoEquals( | |
| 140 device.configuration, fakeDeviceInit.configurations[0]); | |
| 141 }) | |
| 142 .then(() => device.close()); | |
| 143 }); | |
| 144 }, 'device configuration can be set and queried'); | |
| 145 | |
| 146 usb_test(() => { | |
| 147 return getFakeDevice().then(({ device }) => { | |
| 148 assert_equals(device.configuration, null); | |
| 149 return device.open() | |
| 150 .then(() => assertRejectsWithError( | |
| 151 device.selectConfiguration(3), 'NotFoundError', | |
| 152 'The configuration value provided is not supported by the device.')) | |
| 153 .then(() => device.close()); | |
| 154 }); | |
| 155 }, 'selectConfiguration rejects on invalid configurations'); | |
| 156 | |
| 157 usb_test(() => { | |
| 158 return getFakeDevice().then(({ device }) => { | |
| 159 assert_equals(device.configuration, null); | |
| 160 return device.open().then(() => Promise.all([ | |
| 161 assertRejectsWithNotConfiguredError(device.claimInterface(0)), | |
| 162 assertRejectsWithNotConfiguredError(device.releaseInterface(0)), | |
| 163 assertRejectsWithNotConfiguredError(device.selectAlternateInterface(0, 1
)), | |
| 164 assertRejectsWithNotConfiguredError(device.controlTransferIn({ | |
| 165 requestType: 'vendor', | |
| 166 recipient: 'device', | |
| 167 request: 0x42, | |
| 168 value: 0x1234, | |
| 169 index: 0x5678 | |
| 170 }, 7)), | |
| 171 assertRejectsWithNotConfiguredError(device.controlTransferOut({ | |
| 172 requestType: 'vendor', | |
| 173 recipient: 'device', | |
| 174 request: 0x42, | |
| 175 value: 0x1234, | |
| 176 index: 0x5678 | |
| 177 }, new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]))), | |
| 178 assertRejectsWithNotConfiguredError(device.clearHalt('in', 1)), | |
| 179 assertRejectsWithNotConfiguredError(device.transferIn(1, 8)), | |
| 180 assertRejectsWithNotConfiguredError( | |
| 181 device.transferOut(1, new ArrayBuffer(8))), | |
| 182 assertRejectsWithNotConfiguredError( | |
| 183 device.isochronousTransferIn(1, [8])), | |
| 184 assertRejectsWithNotConfiguredError( | |
| 185 device.isochronousTransferOut(1, new ArrayBuffer(8), [8])), | |
| 186 ])).then(() => device.close()); | |
| 187 }); | |
| 188 }, 'methods requiring it reject when the device is unconfigured'); | |
| 189 | |
| 190 usb_test(() => { | |
| 191 return getFakeDevice().then(({ device }) => { | |
| 192 return device.open() | |
| 193 .then(() => device.selectConfiguration(1)) | |
| 194 .then(() => device.claimInterface(0)) | |
| 195 .then(() => { | |
| 196 assert_true(device.configuration.interfaces[0].claimed); | |
| 197 return device.releaseInterface(0); | |
| 198 }) | |
| 199 .then(() => { | |
| 200 assert_false(device.configuration.interfaces[0].claimed); | |
| 201 return device.close(); | |
| 202 }); | |
| 203 }); | |
| 204 }, 'an interface can be claimed and released'); | |
| 205 | |
| 206 usb_test(() => { | |
| 207 return getFakeDevice().then(({ device }) => { | |
| 208 return device.open() | |
| 209 .then(() => device.selectConfiguration(1)) | |
| 210 .then(() => device.claimInterface(0)) | |
| 211 .then(() => { | |
| 212 assert_true(device.configuration.interfaces[0].claimed); | |
| 213 return device.close(0); | |
| 214 }) | |
| 215 .then(() => { | |
| 216 assert_false(device.configuration.interfaces[0].claimed); | |
| 217 }); | |
| 218 }); | |
| 219 }, 'interfaces are released on close'); | |
| 220 | |
| 221 usb_test(() => { | |
| 222 return getFakeDevice().then(({ device }) => { | |
| 223 const message = 'The interface number provided is not supported by the ' + | |
| 224 'device in its current configuration.'; | |
| 225 return device.open() | |
| 226 .then(() => device.selectConfiguration(1)) | |
| 227 .then(() => Promise.all([ | |
| 228 assertRejectsWithError( | |
| 229 device.claimInterface(2), 'NotFoundError', message), | |
| 230 assertRejectsWithError( | |
| 231 device.releaseInterface(2), 'NotFoundError', message), | |
| 232 ])) | |
| 233 .then(() => device.close()); | |
| 234 }); | |
| 235 }, 'a non-existent interface cannot be claimed or released'); | |
| 236 | |
| 237 usb_test(() => { | |
| 238 return getFakeDevice().then(({ device, fakeDevice }) => { | |
| 239 return device.open() | |
| 240 .then(() => device.selectConfiguration(1)) | |
| 241 .then(() => waitForDisconnect(fakeDevice)) | |
| 242 .then(() => assertRejectsWithNotFoundError(device.claimInterface(0))); | |
| 243 }); | |
| 244 }, 'claimInterface rejects when called on a disconnected device'); | |
| 245 | |
| 246 usb_test(() => { | |
| 247 return getFakeDevice().then(({ device, fakeDevice }) => { | |
| 248 return device.open() | |
| 249 .then(() => device.selectConfiguration(1)) | |
| 250 .then(() => device.claimInterface(0)) | |
| 251 .then(() => waitForDisconnect(fakeDevice)) | |
| 252 .then(() => assertRejectsWithNotFoundError(device.releaseInterface(0))); | |
| 253 }); | |
| 254 }, 'releaseInterface rejects when called on a disconnected device'); | |
| 255 | |
| 256 usb_test(() => { | |
| 257 return getFakeDevice().then(({ device }) => { | |
| 258 return device.open() | |
| 259 .then(() => device.selectConfiguration(2)) | |
| 260 .then(() => device.claimInterface(0)) | |
| 261 .then(() => device.selectAlternateInterface(0, 1)) | |
| 262 .then(() => device.close()); | |
| 263 }); | |
| 264 }, 'can select an alternate interface'); | |
| 265 | |
| 266 usb_test(() => { | |
| 267 return getFakeDevice().then(({ device }) => { | |
| 268 return device.open() | |
| 269 .then(() => device.selectConfiguration(2)) | |
| 270 .then(() => device.claimInterface(0)) | |
| 271 .then(() => assertRejectsWithError( | |
| 272 device.selectAlternateInterface(0, 2), 'NotFoundError', | |
| 273 'The alternate setting provided is not supported by the device in ' + | |
| 274 'its current configuration.')) | |
| 275 .then(() => device.close()); | |
| 276 }); | |
| 277 }, 'cannot select a non-existent alternate interface'); | |
| 278 | |
| 279 usb_test(() => { | |
| 280 return getFakeDevice().then(({ device, fakeDevice }) => { | |
| 281 return device.open() | |
| 282 .then(() => device.selectConfiguration(2)) | |
| 283 .then(() => device.claimInterface(0)) | |
| 284 .then(() => waitForDisconnect(fakeDevice)) | |
| 285 .then(() => assertRejectsWithNotFoundError(device.selectAlternateInterface
(0, 1))); | |
| 286 }); | |
| 287 }, 'selectAlternateInterface rejects when called on a disconnected device'); | |
| 288 | |
| 289 usb_test(() => { | |
| 290 return getFakeDevice().then(({ device }) => { | |
| 291 return device.open() | |
| 292 .then(() => device.selectConfiguration(1)) | |
| 293 .then(() => device.controlTransferIn({ | |
| 294 requestType: 'vendor', | |
| 295 recipient: 'device', | |
| 296 request: 0x42, | |
| 297 value: 0x1234, | |
| 298 index: 0x5678 | |
| 299 }, 7)) | |
| 300 .then(result => { | |
| 301 assert_true(result instanceof USBInTransferResult); | |
| 302 assert_equals(result.status, 'ok'); | |
| 303 assert_equals(result.data.byteLength, 7); | |
| 304 assert_equals(result.data.getUint16(0), 0x07); | |
| 305 assert_equals(result.data.getUint8(2), 0x42); | |
| 306 assert_equals(result.data.getUint16(3), 0x1234); | |
| 307 assert_equals(result.data.getUint16(5), 0x5678); | |
| 308 return device.close(); | |
| 309 }); | |
| 310 }); | |
| 311 }, 'can issue IN control transfer'); | |
| 312 | |
| 313 usb_test(() => { | |
| 314 return getFakeDevice().then(({ device, fakeDevice }) => { | |
| 315 return device.open() | |
| 316 .then(() => device.selectConfiguration(1)) | |
| 317 .then(() => waitForDisconnect(fakeDevice)) | |
| 318 .then(() => assertRejectsWithNotFoundError(device.controlTransferIn({ | |
| 319 requestType: 'vendor', | |
| 320 recipient: 'device', | |
| 321 request: 0x42, | |
| 322 value: 0x1234, | |
| 323 index: 0x5678 | |
| 324 }, 7))); | |
| 325 }); | |
| 326 }, 'controlTransferIn rejects when called on a disconnected device'); | |
| 327 | |
| 328 usb_test(() => { | |
| 329 return getFakeDevice().then(({ device }) => { | |
| 330 return device.open() | |
| 331 .then(() => device.selectConfiguration(1)) | |
| 332 .then(() => device.controlTransferOut({ | |
| 333 requestType: 'vendor', | |
| 334 recipient: 'device', | |
| 335 request: 0x42, | |
| 336 value: 0x1234, | |
| 337 index: 0x5678 | |
| 338 }, new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]))) | |
| 339 .then(result => { | |
| 340 assert_true(result instanceof USBOutTransferResult); | |
| 341 assert_equals(result.status, 'ok'); | |
| 342 assert_equals(result.bytesWritten, 8); | |
| 343 return device.close(); | |
| 344 }) | |
| 345 }); | |
| 346 }, 'can issue OUT control transfer'); | |
| 347 | |
| 348 usb_test(() => { | |
| 349 return getFakeDevice().then(({ device, fakeDevice }) => { | |
| 350 return device.open() | |
| 351 .then(() => device.selectConfiguration(1)) | |
| 352 .then(() => waitForDisconnect(fakeDevice)) | |
| 353 .then(() => assertRejectsWithNotFoundError(device.controlTransferOut({ | |
| 354 requestType: 'vendor', | |
| 355 recipient: 'device', | |
| 356 request: 0x42, | |
| 357 value: 0x1234, | |
| 358 index: 0x5678 | |
| 359 }, new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])))); | |
| 360 }); | |
| 361 }, 'controlTransferOut rejects when called on a disconnected device'); | |
| 362 | |
| 363 usb_test(() => { | |
| 364 return getFakeDevice().then(({ device }) => { | |
| 365 let interfaceRequest = { | |
| 366 requestType: 'vendor', | |
| 367 recipient: 'interface', | |
| 368 request: 0x42, | |
| 369 value: 0x1234, | |
| 370 index: 0x5600 // Last byte of index is interface number. | |
| 371 }; | |
| 372 let endpointRequest = { | |
| 373 requestType: 'vendor', | |
| 374 recipient: 'endpoint', | |
| 375 request: 0x42, | |
| 376 value: 0x1234, | |
| 377 index: 0x5681 // Last byte of index is endpoint address. | |
| 378 }; | |
| 379 let data = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]); | |
| 380 return device.open() | |
| 381 .then(() => device.selectConfiguration(1)) | |
| 382 .then(() => Promise.all([ | |
| 383 assertRejectsWithError( | |
| 384 device.controlTransferIn(interfaceRequest, 7), | |
| 385 'InvalidStateError'), | |
| 386 assertRejectsWithError( | |
| 387 device.controlTransferIn(endpointRequest, 7), | |
| 388 'NotFoundError'), | |
| 389 assertRejectsWithError( | |
| 390 device.controlTransferOut(interfaceRequest, data), | |
| 391 'InvalidStateError'), | |
| 392 assertRejectsWithError( | |
| 393 device.controlTransferOut(endpointRequest, data), | |
| 394 'NotFoundError'), | |
| 395 ])) | |
| 396 .then(() => device.claimInterface(0)) | |
| 397 .then(() => Promise.all([ | |
| 398 device.controlTransferIn(interfaceRequest, 7).then(result => { | |
| 399 assert_true(result instanceof USBInTransferResult); | |
| 400 assert_equals(result.status, 'ok'); | |
| 401 assert_equals(result.data.byteLength, 7); | |
| 402 assert_equals(result.data.getUint16(0), 0x07); | |
| 403 assert_equals(result.data.getUint8(2), 0x42); | |
| 404 assert_equals(result.data.getUint16(3), 0x1234); | |
| 405 assert_equals(result.data.getUint16(5), 0x5600); | |
| 406 }), | |
| 407 device.controlTransferIn(endpointRequest, 7).then(result => { | |
| 408 assert_true(result instanceof USBInTransferResult); | |
| 409 assert_equals(result.status, 'ok'); | |
| 410 assert_equals(result.data.byteLength, 7); | |
| 411 assert_equals(result.data.getUint16(0), 0x07); | |
| 412 assert_equals(result.data.getUint8(2), 0x42); | |
| 413 assert_equals(result.data.getUint16(3), 0x1234); | |
| 414 assert_equals(result.data.getUint16(5), 0x5681); | |
| 415 }), | |
| 416 device.controlTransferOut(interfaceRequest, data), | |
| 417 device.controlTransferOut(endpointRequest, data), | |
| 418 ])) | |
| 419 .then(() => device.close()); | |
| 420 }); | |
| 421 }, 'requests to interfaces and endpoint require an interface claim'); | |
| 422 | |
| 423 usb_test(() => { | |
| 424 return getFakeDevice().then(({ device }) => { | |
| 425 return device.open() | |
| 426 .then(() => device.selectConfiguration(1)) | |
| 427 .then(() => device.claimInterface(0)) | |
| 428 .then(() => device.clearHalt('in', 1)) | |
| 429 .then(() => device.close()); | |
| 430 }); | |
| 431 }, 'can clear a halt condition'); | |
| 432 | |
| 433 usb_test(() => { | |
| 434 return getFakeDevice().then(({ device, fakeDevice }) => { | |
| 435 return device.open() | |
| 436 .then(() => device.selectConfiguration(1)) | |
| 437 .then(() => device.claimInterface(0)) | |
| 438 .then(() => waitForDisconnect(fakeDevice)) | |
| 439 .then(() => assertRejectsWithNotFoundError(device.clearHalt('in', 1))); | |
| 440 }); | |
| 441 }, 'clearHalt rejects when called on a disconnected device'); | |
| 442 | |
| 443 usb_test(() => { | |
| 444 return getFakeDevice().then(({ device }) => { | |
| 445 let data = new DataView(new ArrayBuffer(1024)); | |
| 446 for (let i = 0; i < 1024; ++i) | |
| 447 data.setUint8(i, i & 0xff); | |
| 448 const notFoundMessage = 'The specified endpoint is not part of a claimed ' + | |
| 449 'and selected alternate interface.'; | |
| 450 const rangeError = 'The specified endpoint number is out of range.'; | |
| 451 return device.open() | |
| 452 .then(() => device.selectConfiguration(1)) | |
| 453 .then(() => device.claimInterface(0)) | |
| 454 .then(() => Promise.all([ | |
| 455 assertRejectsWithError(device.transferIn(2, 8), | |
| 456 'NotFoundError', notFoundMessage), // Unclaimed | |
| 457 assertRejectsWithError(device.transferIn(3, 8), 'NotFoundError', | |
| 458 notFoundMessage), // Non-existent | |
| 459 assertRejectsWithError( | |
| 460 device.transferIn(16, 8), 'IndexSizeError', rangeError), | |
| 461 assertRejectsWithError(device.transferOut(2, data), | |
| 462 'NotFoundError', notFoundMessage), // Unclaimed | |
| 463 assertRejectsWithError(device.transferOut(3, data), 'NotFoundError', | |
| 464 notFoundMessage), // Non-existent | |
| 465 assertRejectsWithError( | |
| 466 device.transferOut(16, data), 'IndexSizeError', rangeError), | |
| 467 ])); | |
| 468 }); | |
| 469 }, 'transfers to unavailable endpoints are rejected'); | |
| 470 | |
| 471 usb_test(() => { | |
| 472 return getFakeDevice().then(({ device }) => { | |
| 473 return device.open() | |
| 474 .then(() => device.selectConfiguration(1)) | |
| 475 .then(() => device.claimInterface(0)) | |
| 476 .then(() => device.transferIn(1, 8)) | |
| 477 .then(result => { | |
| 478 assert_true(result instanceof USBInTransferResult); | |
| 479 assert_equals(result.status, 'ok'); | |
| 480 assert_equals(result.data.byteLength, 8); | |
| 481 for (let i = 0; i < 8; ++i) | |
| 482 assert_equals(result.data.getUint8(i), i, 'mismatch at byte ' + i); | |
| 483 return device.close(); | |
| 484 }); | |
| 485 }); | |
| 486 }, 'can issue IN interrupt transfer'); | |
| 487 | |
| 488 usb_test(() => { | |
| 489 return getFakeDevice().then(({ device }) => { | |
| 490 return device.open() | |
| 491 .then(() => device.selectConfiguration(1)) | |
| 492 .then(() => device.claimInterface(1)) | |
| 493 .then(() => device.transferIn(2, 1024)) | |
| 494 .then(result => { | |
| 495 assert_true(result instanceof USBInTransferResult); | |
| 496 assert_equals(result.status, 'ok'); | |
| 497 assert_equals(result.data.byteLength, 1024); | |
| 498 for (let i = 0; i < 1024; ++i) | |
| 499 assert_equals(result.data.getUint8(i), i & 0xff, | |
| 500 'mismatch at byte ' + i); | |
| 501 return device.close(); | |
| 502 }); | |
| 503 }); | |
| 504 }, 'can issue IN bulk transfer'); | |
| 505 | |
| 506 usb_test(() => { | |
| 507 return getFakeDevice().then(({ device, fakeDevice }) => { | |
| 508 return device.open() | |
| 509 .then(() => device.selectConfiguration(1)) | |
| 510 .then(() => device.claimInterface(1)) | |
| 511 .then(() => waitForDisconnect(fakeDevice)) | |
| 512 .then(() => assertRejectsWithNotFoundError(device.transferIn(2, 1024))); | |
| 513 }); | |
| 514 }, 'transferIn rejects if called on a disconnected device'); | |
| 515 | |
| 516 usb_test(() => { | |
| 517 return getFakeDevice().then(({ device }) => { | |
| 518 return device.open() | |
| 519 .then(() => device.selectConfiguration(1)) | |
| 520 .then(() => device.claimInterface(1)) | |
| 521 .then(() => { | |
| 522 let data = new DataView(new ArrayBuffer(1024)); | |
| 523 for (let i = 0; i < 1024; ++i) | |
| 524 data.setUint8(i, i & 0xff); | |
| 525 return device.transferOut(2, data); | |
| 526 }) | |
| 527 .then(result => { | |
| 528 assert_true(result instanceof USBOutTransferResult); | |
| 529 assert_equals(result.status, 'ok'); | |
| 530 assert_equals(result.bytesWritten, 1024); | |
| 531 return device.close(); | |
| 532 }); | |
| 533 }); | |
| 534 }, 'can issue OUT bulk transfer'); | |
| 535 | |
| 536 usb_test(() => { | |
| 537 return getFakeDevice().then(({ device, fakeDevice }) => { | |
| 538 return device.open() | |
| 539 .then(() => device.selectConfiguration(1)) | |
| 540 .then(() => device.claimInterface(1)) | |
| 541 .then(() => { | |
| 542 let data = new DataView(new ArrayBuffer(1024)); | |
| 543 for (let i = 0; i < 1024; ++i) | |
| 544 data.setUint8(i, i & 0xff); | |
| 545 return waitForDisconnect(fakeDevice) | |
| 546 .then(() => assertRejectsWithNotFoundError(device.transferOut(2, data)
)); | |
| 547 }); | |
| 548 }); | |
| 549 }, 'transferOut rejects if called on a disconnected device'); | |
| 550 | |
| 551 usb_test(() => { | |
| 552 return getFakeDevice().then(({ device }) => { | |
| 553 return device.open() | |
| 554 .then(() => device.selectConfiguration(2)) | |
| 555 .then(() => device.claimInterface(0)) | |
| 556 .then(() => device.selectAlternateInterface(0, 1)) | |
| 557 .then(() => device.isochronousTransferIn( | |
| 558 1, [64, 64, 64, 64, 64, 64, 64, 64])) | |
| 559 .then(result => { | |
| 560 assert_true(result instanceof USBIsochronousInTransferResult); | |
| 561 assert_equals(result.data.byteLength, 64 * 8, 'buffer size'); | |
| 562 assert_equals(result.packets.length, 8, 'number of packets'); | |
| 563 let byteOffset = 0; | |
| 564 for (let i = 0; i < result.packets.length; ++i) { | |
| 565 assert_true( | |
| 566 result.packets[i] instanceof USBIsochronousInTransferPacket); | |
| 567 assert_equals(result.packets[i].status, 'ok'); | |
| 568 assert_equals(result.packets[i].data.byteLength, 64); | |
| 569 assert_equals(result.packets[i].data.buffer, result.data.buffer); | |
| 570 assert_equals(result.packets[i].data.byteOffset, byteOffset); | |
| 571 for (let j = 0; j < 64; ++j) | |
| 572 assert_equals(result.packets[i].data.getUint8(j), j & 0xff, | |
| 573 'mismatch at byte ' + j + ' of packet ' + i); | |
| 574 byteOffset += result.packets[i].data.byteLength; | |
| 575 } | |
| 576 return device.close(); | |
| 577 }); | |
| 578 }); | |
| 579 }, 'can issue IN isochronous transfer'); | |
| 580 | |
| 581 usb_test(() => { | |
| 582 return getFakeDevice().then(({ device, fakeDevice }) => { | |
| 583 return device.open() | |
| 584 .then(() => device.selectConfiguration(2)) | |
| 585 .then(() => device.claimInterface(0)) | |
| 586 .then(() => device.selectAlternateInterface(0, 1)) | |
| 587 .then(() => waitForDisconnect(fakeDevice)) | |
| 588 .then(() => assertRejectsWithNotFoundError(device.isochronousTransferIn( | |
| 589 1, [64, 64, 64, 64, 64, 64, 64, 64]))); | |
| 590 }); | |
| 591 }, 'isochronousTransferIn rejects when called on a disconnected device'); | |
| 592 | |
| 593 usb_test(() => { | |
| 594 return getFakeDevice().then(({ device }) => { | |
| 595 return device.open() | |
| 596 .then(() => device.selectConfiguration(2)) | |
| 597 .then(() => device.claimInterface(0)) | |
| 598 .then(() => device.selectAlternateInterface(0, 1)) | |
| 599 .then(() => { | |
| 600 let data = new DataView(new ArrayBuffer(64 * 8)); | |
| 601 for (let i = 0; i < 8; ++i) { | |
| 602 for (let j = 0; j < 64; ++j) | |
| 603 data.setUint8(i * j, j & 0xff); | |
| 604 } | |
| 605 return device.isochronousTransferOut( | |
| 606 1, data, [64, 64, 64, 64, 64, 64, 64, 64]); | |
| 607 }) | |
| 608 .then(result => { | |
| 609 assert_true(result instanceof USBIsochronousOutTransferResult); | |
| 610 assert_equals(result.packets.length, 8, 'number of packets'); | |
| 611 let byteOffset = 0; | |
| 612 for (let i = 0; i < result.packets.length; ++i) { | |
| 613 assert_true( | |
| 614 result.packets[i] instanceof USBIsochronousOutTransferPacket); | |
| 615 assert_equals(result.packets[i].status, 'ok'); | |
| 616 assert_equals(result.packets[i].bytesWritten, 64); | |
| 617 } | |
| 618 return device.close(); | |
| 619 }); | |
| 620 }); | |
| 621 }, 'can issue OUT isochronous transfer'); | |
| 622 | |
| 623 usb_test(() => { | |
| 624 return getFakeDevice().then(({ device, fakeDevice }) => { | |
| 625 return device.open() | |
| 626 .then(() => device.selectConfiguration(2)) | |
| 627 .then(() => device.claimInterface(0)) | |
| 628 .then(() => device.selectAlternateInterface(0, 1)) | |
| 629 .then(() => { | |
| 630 let data = new DataView(new ArrayBuffer(64 * 8)); | |
| 631 for (let i = 0; i < 8; ++i) { | |
| 632 for (let j = 0; j < 64; ++j) | |
| 633 data.setUint8(i * j, j & 0xff); | |
| 634 } | |
| 635 return waitForDisconnect(fakeDevice) | |
| 636 .then(() => assertRejectsWithNotFoundError(device.isochronousTransferO
ut( | |
| 637 1, data, [64, 64, 64, 64, 64, 64, 64, 64]))); | |
| 638 }); | |
| 639 }); | |
| 640 }, 'isochronousTransferOut rejects when called on a disconnected device'); | |
| 641 | |
| 642 usb_test(() => { | |
| 643 return getFakeDevice().then(({ device }) => { | |
| 644 return device.open().then(() => device.reset()).then(() => device.close()); | |
| 645 }); | |
| 646 }, 'can reset the device'); | |
| 647 | |
| 648 usb_test(() => { | |
| 649 return getFakeDevice().then(({ device, fakeDevice }) => { | |
| 650 return device.open() | |
| 651 .then(() => waitForDisconnect(fakeDevice)) | |
| 652 .then(() => assertRejectsWithNotFoundError(device.reset())); | |
| 653 }); | |
| 654 }, 'resetDevice rejects when called on a disconnected device'); | |
| 655 </script> | |
| OLD | NEW |