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

Side by Side Diff: third_party/WebKit/LayoutTests/usb/resources/webusb-test.js

Issue 2816663002: Ensure tests don't depend on fake devices being added synchronously (Closed)
Patch Set: Define FakeUSBDevice class only once Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 'use strict'; 1 'use strict';
2 2
3 // This polyfil library implements the following WebIDL: 3 // This polyfil library implements the following WebIDL:
4 // 4 //
5 // partial interface USB { 5 // partial interface USB {
6 // [SameObject] readonly attribute USBTest test; 6 // [SameObject] readonly attribute USBTest test;
7 // } 7 // }
8 // 8 //
9 // interface USBTest { 9 // interface USBTest {
10 // attribute EventHandler ondeviceclose; 10 // attribute EventHandler ondeviceclose;
11 // attribute DOMString? chosenDevice; 11 // attribute FakeUSBDevice? chosenDevice;
12 // attribute FrozenArray<USBDeviceFilter>? lastFilters; 12 // attribute FrozenArray<USBDeviceFilter>? lastFilters;
13 // 13 //
14 // Promise<void> initialize(); 14 // Promise<void> initialize();
15 // Promise<void> attachToWindow(Window window); 15 // Promise<void> attachToWindow(Window window);
16 // DOMString addFakeDevice(FakeUSBDeviceInit deviceInit); 16 // FakeUSBDevice addFakeDevice(FakeUSBDeviceInit deviceInit);
17 // void removeFakeDevice(DOMString);
18 // void reset(); 17 // void reset();
19 // }; 18 // };
20 // 19 //
20 // interface FakeUSBDevice {
21 // void disconnect();
22 // };
23 //
21 // dictionary FakeUSBDeviceInit { 24 // dictionary FakeUSBDeviceInit {
22 // octet usbVersionMajor; 25 // octet usbVersionMajor;
23 // octet usbVersionMinor; 26 // octet usbVersionMinor;
24 // octet usbVersionSubminor; 27 // octet usbVersionSubminor;
25 // octet deviceClass; 28 // octet deviceClass;
26 // octet deviceSubclass; 29 // octet deviceSubclass;
27 // octet deviceProtocol; 30 // octet deviceProtocol;
28 // unsigned short vendorId; 31 // unsigned short vendorId;
29 // unsigned short productId; 32 // unsigned short productId;
30 // octet deviceVersionMajor; 33 // octet deviceVersionMajor;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 // The global mojo object contains the Mojo JS binding modules loaded during 72 // The global mojo object contains the Mojo JS binding modules loaded during
70 // initialization. 73 // initialization.
71 let mojo = null; 74 let mojo = null;
72 75
73 // These variables are logically members of the USBTest class but are defined 76 // These variables are logically members of the USBTest class but are defined
74 // here to hide them from being visible as fields of navigator.usb.test. 77 // here to hide them from being visible as fields of navigator.usb.test.
75 let g_initializePromise = null; 78 let g_initializePromise = null;
76 let g_chooserService = null; 79 let g_chooserService = null;
77 let g_deviceManager = null; 80 let g_deviceManager = null;
78 let g_closeListener = null; 81 let g_closeListener = null;
82 let g_nextGuid = 0;
79 83
80 function fakeDeviceInitToDeviceInfo(guid, init) { 84 function fakeDeviceInitToDeviceInfo(guid, init) {
81 let deviceInfo = { 85 let deviceInfo = {
82 guid: guid + "", 86 guid: guid + "",
83 usb_version_major: init.usbVersionMajor, 87 usb_version_major: init.usbVersionMajor,
84 usb_version_minor: init.usbVersionMinor, 88 usb_version_minor: init.usbVersionMinor,
85 usb_version_subminor: init.usbVersionSubminor, 89 usb_version_subminor: init.usbVersionSubminor,
86 class_code: init.deviceClass, 90 class_code: init.deviceClass,
87 subclass_code: init.deviceSubclass, 91 subclass_code: init.deviceSubclass,
88 protocol_code: init.deviceProtocol, 92 protocol_code: init.deviceProtocol,
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 } 344 }
341 return Promise.resolve({ packets: packets }); 345 return Promise.resolve({ packets: packets });
342 } 346 }
343 } 347 }
344 348
345 class FakeDeviceManager { 349 class FakeDeviceManager {
346 constructor() { 350 constructor() {
347 this.bindingSet_ = 351 this.bindingSet_ =
348 new mojo.bindings.BindingSet(mojo.deviceManager.DeviceManager); 352 new mojo.bindings.BindingSet(mojo.deviceManager.DeviceManager);
349 this.devices_ = new Map(); 353 this.devices_ = new Map();
354 this.devicesByGuid_ = new Map();
350 this.client_ = null; 355 this.client_ = null;
356 this.nextGuid_ = 0;
351 } 357 }
352 358
353 addBinding(handle) { 359 addBinding(handle) {
354 this.bindingSet_.addBinding(this, handle); 360 this.bindingSet_.addBinding(this, handle);
355 } 361 }
356 362
357 addDevice(info) { 363 addDevice(fakeDevice, info) {
358 let device = { 364 let device = {
359 guid: this.nextGuid_++ + "", 365 fakeDevice: fakeDevice,
366 guid: (this.nextGuid_++).toString(),
360 info: info, 367 info: info,
361 bindingArray: [] 368 bindingArray: []
362 }; 369 };
363 this.devices_.set(device.guid, device); 370 this.devices_.set(fakeDevice, device);
371 this.devicesByGuid_.set(device.guid, device);
364 if (this.client_) 372 if (this.client_)
365 this.client_.onDeviceAdded(fakeDeviceInitToDeviceInfo(device.guid, info)); 373 this.client_.onDeviceAdded(fakeDeviceInitToDeviceInfo(device.guid, info));
366 return device.guid;
367 } 374 }
368 375
369 removeDevice(guid) { 376 removeDevice(fakeDevice) {
370 let device = this.devices_.get(guid); 377 let device = this.devices_.get(fakeDevice);
378 if (!device)
379 throw new Error('Cannot remove unknown device.');
380
371 for (var binding of device.bindingArray) 381 for (var binding of device.bindingArray)
372 binding.close(); 382 binding.close();
373 this.devices_.delete(guid); 383 this.devices_.delete(device.fakeDevice);
384 this.devicesByGuid_.delete(device.guid);
374 if (this.client_) { 385 if (this.client_) {
375 this.client_.onDeviceRemoved( 386 this.client_.onDeviceRemoved(
376 fakeDeviceInitToDeviceInfo(guid, device.info)); 387 fakeDeviceInitToDeviceInfo(device.guid, device.info));
377 } 388 }
378 } 389 }
379 390
380 removeAllDevices() { 391 removeAllDevices() {
381 this.devices_.forEach(device => { 392 this.devices_.forEach(device => {
382 for (var binding of device.bindingArray) 393 for (var binding of device.bindingArray)
383 binding.close(); 394 binding.close();
384 this.client_.onDeviceRemoved( 395 this.client_.onDeviceRemoved(
385 fakeDeviceInitToDeviceInfo(device.guid, device.info)); 396 fakeDeviceInitToDeviceInfo(device.guid, device.info));
386 }); 397 });
387 this.devices_.clear(); 398 this.devices_.clear();
399 this.devicesByGuid_.clear();
388 } 400 }
389 401
390 getDevices(options) { 402 getDevices(options) {
391 let devices = []; 403 let devices = [];
392 this.devices_.forEach(device => { 404 this.devices_.forEach(device => {
393 devices.push(fakeDeviceInitToDeviceInfo(device.guid, device.info)); 405 devices.push(fakeDeviceInitToDeviceInfo(device.guid, device.info));
394 }); 406 });
395 return Promise.resolve({ results: devices }); 407 return Promise.resolve({ results: devices });
396 } 408 }
397 409
398 getDevice(guid, request) { 410 getDevice(guid, request) {
399 let device = this.devices_.get(guid); 411 let device = this.devicesByGuid_.get(guid);
400 if (device) { 412 if (device) {
401 let binding = new mojo.bindings.Binding( 413 let binding = new mojo.bindings.Binding(
402 mojo.device.Device, new FakeDevice(device.info), request); 414 mojo.device.Device, new FakeDevice(device.info), request);
403 binding.setConnectionErrorHandler(() => { 415 binding.setConnectionErrorHandler(() => {
404 if (g_closeListener) 416 if (g_closeListener)
405 g_closeListener(guid); 417 g_closeListener(device.fakeDevice);
406 }); 418 });
407 device.bindingArray.push(binding); 419 device.bindingArray.push(binding);
408 } else { 420 } else {
409 request.close(); 421 request.close();
410 } 422 }
411 } 423 }
412 424
413 setClient(client) { 425 setClient(client) {
414 this.client_ = client; 426 this.client_ = client;
415 } 427 }
416 } 428 }
417 429
418 class FakeChooserService { 430 class FakeChooserService {
419 constructor() { 431 constructor() {
420 this.bindingSet_ = new mojo.bindings.BindingSet( 432 this.bindingSet_ = new mojo.bindings.BindingSet(
421 mojo.chooserService.ChooserService); 433 mojo.chooserService.ChooserService);
422 this.chosenDevice_ = null; 434 this.chosenDevice_ = null;
423 this.lastFilters_ = null; 435 this.lastFilters_ = null;
424 } 436 }
425 437
426 addBinding(handle) { 438 addBinding(handle) {
427 this.bindingSet_.addBinding(this, handle); 439 this.bindingSet_.addBinding(this, handle);
428 } 440 }
429 441
430 setChosenDevice(guid) { 442 setChosenDevice(fakeDevice) {
431 this.chosenDeviceGuid_ = guid; 443 this.chosenDevice_ = fakeDevice;
432 } 444 }
433 445
434 getPermission(deviceFilters) { 446 getPermission(deviceFilters) {
435 this.lastFilters_ = convertMojoDeviceFilters(deviceFilters); 447 this.lastFilters_ = convertMojoDeviceFilters(deviceFilters);
436 let device = g_deviceManager.devices_.get(this.chosenDeviceGuid_); 448 let device = g_deviceManager.devices_.get(this.chosenDevice_);
437 if (device) { 449 if (device) {
438 return Promise.resolve({ 450 return Promise.resolve({
439 result: fakeDeviceInitToDeviceInfo(device.guid, device.info) 451 result: fakeDeviceInitToDeviceInfo(device.guid, device.info)
440 }); 452 });
441 } else { 453 } else {
442 return Promise.resolve({ result: null }); 454 return Promise.resolve({ result: null });
443 } 455 }
444 } 456 }
445 } 457 }
446 458
459 // Unlike FakeDevice this class is exported to callers of USBTest.addFakeDevice.
460 class FakeUSBDevice {
461 disconnect() {
462 setTimeout(() => g_deviceManager.removeDevice(this), 0);
463 }
464 }
465
447 class USBTest { 466 class USBTest {
448 constructor() {} 467 constructor() {}
449 468
450 initialize() { 469 initialize() {
451 if (!g_initializePromise) { 470 if (!g_initializePromise) {
452 g_initializePromise = new Promise(resolve => { 471 g_initializePromise = new Promise(resolve => {
453 window.define = gin.define; // Mojo modules expect this. 472 window.define = gin.define; // Mojo modules expect this.
454 473
455 gin.define('WebUSB Test Mocks', [ 474 gin.define('WebUSB Test Mocks', [
456 'content/public/renderer/frame_interfaces', 475 'content/public/renderer/frame_interfaces',
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 handle => g_chooserService.addBinding(handle)); 534 handle => g_chooserService.addBinding(handle));
516 resolve(); 535 resolve();
517 }); 536 });
518 }); 537 });
519 } 538 }
520 539
521 addFakeDevice(deviceInit) { 540 addFakeDevice(deviceInit) {
522 if (!g_deviceManager) 541 if (!g_deviceManager)
523 throw new Error('Call initialize() before addFakeDevice().'); 542 throw new Error('Call initialize() before addFakeDevice().');
524 543
525 return g_deviceManager.addDevice(deviceInit); 544 // |addDevice| and |removeDevice| are called in a setTimeout callback so
526 } 545 // that tests do not rely on the device being immediately available which
527 546 // may not be true for all implementations of this test API.
528 removeFakeDevice(guid) { 547 let fakeDevice = new FakeUSBDevice();
529 if (!g_deviceManager) 548 setTimeout(() => g_deviceManager.addDevice(fakeDevice, deviceInit), 0);
530 throw new Error('Call initialize() before removeFakeDevice().'); 549 return fakeDevice;
531
532 return g_deviceManager.removeDevice(guid);
533 } 550 }
534 551
535 set ondeviceclose(func) { 552 set ondeviceclose(func) {
536 g_closeListener = func; 553 g_closeListener = func;
537 } 554 }
538 555
539 set chosenDevice(guid) { 556 set chosenDevice(fakeDevice) {
540 if (!g_chooserService) 557 if (!g_chooserService)
541 throw new Error('Call initialize() before setting chosenDevice.'); 558 throw new Error('Call initialize() before setting chosenDevice.');
542 559
543 g_chooserService.setChosenDevice(guid); 560 g_chooserService.setChosenDevice(fakeDevice);
544 } 561 }
545 562
546 get lastFilters() { 563 get lastFilters() {
547 if (!g_chooserService) 564 if (!g_chooserService)
548 throw new Error('Call initialize() before getting lastFilters.'); 565 throw new Error('Call initialize() before getting lastFilters.');
549 566
550 return g_chooserService.lastFilters_; 567 return g_chooserService.lastFilters_;
551 } 568 }
552 569
553 reset() { 570 reset() {
554 if (!g_deviceManager || !g_chooserService) 571 if (!g_deviceManager || !g_chooserService)
555 throw new Error('Call initialize() before reset().'); 572 throw new Error('Call initialize() before reset().');
556 573
557 g_deviceManager.removeAllDevices(); 574 g_deviceManager.removeAllDevices();
558 g_chooserService.setChosenDevice(null); 575 g_chooserService.setChosenDevice(null);
559 g_closeListener = null; 576 g_closeListener = null;
560 } 577 }
561 } 578 }
562 579
563 navigator.usb.test = new USBTest(); 580 navigator.usb.test = new USBTest();
564 581
565 })(); 582 })();
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/usb/resources/usb-helpers.js ('k') | third_party/WebKit/LayoutTests/usb/usb.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698