// META: timeout=long
// META: script=/resources/test-only-api.js
// META: script=/webusb/resources/fake-devices.js
// META: script=/webusb/resources/usb-helpers.js
'use strict';

function detachBuffer(buffer) {
  if (self.GLOBAL.isWindow())
    window.postMessage('', '*', [buffer]);
  else
    self.postMessage('', [buffer]);
}

usb_test((t) => {
  return getFakeDevice().then(({device, fakeDevice}) => {
    return waitForDisconnect(fakeDevice)
        .then(() => promise_rejects_dom(t, 'NotFoundError', device.open()));
  });
}, 'open rejects when called on a disconnected device');

usb_test(() => {
  return getFakeDevice().then(({ device, fakeDevice }) => {
    return device.open()
      .then(() => waitForDisconnect(fakeDevice))
      .then(() => {
        assert_false(device.opened);
      });
  });
}, 'disconnection closes the device');

usb_test(() => {
  return getFakeDevice().then(({ device }) => {
    assert_false(device.opened);
    return device.open().then(() => {
      assert_true(device.opened);
      return device.close().then(() => {
        assert_false(device.opened);
      });
    });
  });
}, 'a device can be opened and closed');

usb_test(() => {
  return getFakeDevice().then(({ device }) => {
    return device.open()
      .then(() => device.open())
      .then(() => device.open())
      .then(() => device.open())
      .then(() => device.close())
      .then(() => device.close())
      .then(() => device.close())
      .then(() => device.close());
  });
}, 'open and close can be called multiple times');

usb_test(async (t) => {
  let { device } = await getFakeDevice();
  await Promise.all([
    device.open(),
    promise_rejects_dom(t, 'InvalidStateError', device.open()),
    promise_rejects_dom(t, 'InvalidStateError', device.close()),
  ]);
  await Promise.all([
    device.close(),
    promise_rejects_dom(t, 'InvalidStateError', device.open()),
    promise_rejects_dom(t, 'InvalidStateError', device.close()),
  ]);
}, 'open and close cannot be called again while open or close are in progress');

usb_test(async (t) => {
  let { device } = await getFakeDevice();
  await device.open();
  return Promise.all([
    device.selectConfiguration(1),
    promise_rejects_dom(t, 'InvalidStateError', device.claimInterface(0)),
    promise_rejects_dom(t, 'InvalidStateError', device.releaseInterface(0)),
    promise_rejects_dom(t, 'InvalidStateError', device.open()),
    promise_rejects_dom(t, 'InvalidStateError', device.selectConfiguration(1)),
    promise_rejects_dom(t, 'InvalidStateError', device.reset()),
    promise_rejects_dom(
        t, 'InvalidStateError', device.selectAlternateInterface(0, 0)),
    promise_rejects_dom(t, 'InvalidStateError', device.controlTransferOut({
      requestType: 'standard',
      recipient: 'interface',
      request: 0x42,
      value: 0x1234,
      index: 0x0000,
    })),
    promise_rejects_dom(
        t, 'InvalidStateError',
        device.controlTransferOut(
            {
              requestType: 'standard',
              recipient: 'interface',
              request: 0x42,
              value: 0x1234,
              index: 0x0000,
            },
            new Uint8Array([1, 2, 3]))),
    promise_rejects_dom(
        t, 'InvalidStateError',
        device.controlTransferIn(
            {
              requestType: 'standard',
              recipient: 'interface',
              request: 0x42,
              value: 0x1234,
              index: 0x0000
            },
            0)),
    promise_rejects_dom(t, 'InvalidStateError', device.close()),
  ]);
}, 'device operations reject if an device state change is in progress');

usb_test((t) => {
  return getFakeDevice().then(({device, fakeDevice}) => {
    return device.open()
        .then(() => waitForDisconnect(fakeDevice))
        .then(() => promise_rejects_dom(t, 'NotFoundError', device.close()));
  });
}, 'close rejects when called on a disconnected device');

usb_test((t) => {
  return getFakeDevice().then(({device, fakeDevice}) => {
    return device.open()
        .then(() => waitForDisconnect(fakeDevice))
        .then(
            () => promise_rejects_dom(
                t, 'NotFoundError', device.selectConfiguration(1)));
  });
}, 'selectConfiguration rejects when called on a disconnected device');

usb_test((t) => {
  return getFakeDevice().then(({device}) => Promise.all([
    promise_rejects_dom(t, 'InvalidStateError', device.selectConfiguration(1)),
    promise_rejects_dom(t, 'InvalidStateError', device.claimInterface(0)),
    promise_rejects_dom(t, 'InvalidStateError', device.releaseInterface(0)),
    promise_rejects_dom(
        t, 'InvalidStateError', device.selectAlternateInterface(0, 1)),
    promise_rejects_dom(
        t, 'InvalidStateError',
        device.controlTransferIn(
            {
              requestType: 'vendor',
              recipient: 'device',
              request: 0x42,
              value: 0x1234,
              index: 0x5678
            },
            7)),
    promise_rejects_dom(
        t, 'InvalidStateError',
        device.controlTransferOut(
            {
              requestType: 'vendor',
              recipient: 'device',
              request: 0x42,
              value: 0x1234,
              index: 0x5678
            },
            new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]))),
    promise_rejects_dom(t, 'InvalidStateError', device.clearHalt('in', 1)),
    promise_rejects_dom(t, 'InvalidStateError', device.transferIn(1, 8)),
    promise_rejects_dom(
        t, 'InvalidStateError', device.transferOut(1, new ArrayBuffer(8))),
    promise_rejects_dom(
        t, 'InvalidStateError', device.isochronousTransferIn(1, [8])),
    promise_rejects_dom(
        t, 'InvalidStateError',
        device.isochronousTransferOut(1, new ArrayBuffer(8), [8])),
    promise_rejects_dom(t, 'InvalidStateError', device.reset())
  ]));
}, 'methods requiring it reject when the device is not open');

usb_test(() => {
  return getFakeDevice().then(({ device }) => {
    assert_equals(device.configuration, null);
    return device.open()
      .then(() => {
        assert_equals(device.configuration, null);
        return device.selectConfiguration(1);
      })
      .then(() => {
        assertDeviceInfoEquals(
            device.configuration, fakeDeviceInit.configurations[0]);
      })
      .then(() => device.close());
  });
}, 'device configuration can be set and queried');

usb_test(async () => {
  let { device } = await getFakeDevice();
  assert_equals(device.configuration, null);
  await device.open();
  assert_equals(device.configuration, null);
  await device.selectConfiguration(1);
  await device.selectConfiguration(1);
  assertDeviceInfoEquals(
      device.configuration, fakeDeviceInit.configurations[0]);
  await device.selectConfiguration(2);
  assertDeviceInfoEquals(
      device.configuration, fakeDeviceInit.configurations[1]);
  await device.close();
}, 'a device configuration value can be set again');

usb_test((t) => {
  return getFakeDevice().then(({ device }) => {
    assert_equals(device.configuration, null);
    return device.open()
        .then(
            () => promise_rejects_dom(
                t, 'NotFoundError', device.selectConfiguration(10)))
        .then(() => device.close());
  });
}, 'selectConfiguration rejects on invalid configurations');

usb_test((t) => {
  return getFakeDevice().then(({ device }) => {
    assert_equals(device.configuration, null);
    return device.open()
        .then(() => Promise.all([
          promise_rejects_dom(t, 'InvalidStateError', device.claimInterface(0)),
          promise_rejects_dom(
              t, 'InvalidStateError', device.releaseInterface(0)),
          promise_rejects_dom(
              t, 'InvalidStateError', device.selectAlternateInterface(0, 1)),
          promise_rejects_dom(
              t, 'InvalidStateError', device.clearHalt('in', 1)),
          promise_rejects_dom(t, 'InvalidStateError', device.transferIn(1, 8)),
          promise_rejects_dom(
              t, 'InvalidStateError',
              device.transferOut(1, new ArrayBuffer(8))),
          promise_rejects_dom(
              t, 'InvalidStateError', device.isochronousTransferIn(1, [8])),
          promise_rejects_dom(
              t, 'InvalidStateError',
              device.isochronousTransferOut(1, new ArrayBuffer(8), [8])),
        ]))
        .then(() => device.close());
  });
}, 'methods requiring it reject when the device is unconfigured');

usb_test(async () => {
  let { device } = await getFakeDevice();
  await device.open();
  await device.selectConfiguration(1);
  assert_false(device.configuration.interfaces[0].claimed);
  assert_false(device.configuration.interfaces[1].claimed);

  await device.claimInterface(0);
  assert_true(device.configuration.interfaces[0].claimed);
  assert_false(device.configuration.interfaces[1].claimed);

  await device.claimInterface(1);
  assert_true(device.configuration.interfaces[0].claimed);
  assert_true(device.configuration.interfaces[1].claimed);

  await device.releaseInterface(0);
  assert_false(device.configuration.interfaces[0].claimed);
  assert_true(device.configuration.interfaces[1].claimed);

  await device.releaseInterface(1);
  assert_false(device.configuration.interfaces[0].claimed);
  assert_false(device.configuration.interfaces[1].claimed);

  await device.close();
}, 'interfaces can be claimed and released');

usb_test(async () => {
  let { device } = await getFakeDevice();
  await device.open();
  await device.selectConfiguration(1);
  assert_false(device.configuration.interfaces[0].claimed);
  assert_false(device.configuration.interfaces[1].claimed);

  await Promise.all([device.claimInterface(0),
                     device.claimInterface(1)]);
  assert_true(device.configuration.interfaces[0].claimed);
  assert_true(device.configuration.interfaces[1].claimed);

  await Promise.all([device.releaseInterface(0),
                     device.releaseInterface(1)]);
  assert_false(device.configuration.interfaces[0].claimed);
  assert_false(device.configuration.interfaces[1].claimed);

  await device.close();
}, 'interfaces can be claimed and released in parallel');

usb_test(async () => {
  let { device } = await getFakeDevice()
  await device.open();
  await device.selectConfiguration(1);
  await device.claimInterface(0);
  assert_true(device.configuration.interfaces[0].claimed);
  await device.claimInterface(0);
  assert_true(device.configuration.interfaces[0].claimed);
  await device.close();
}, 'an interface can be claimed multiple times');

usb_test(async () => {
  let { device } = await getFakeDevice();
  await device.open();
  await device.selectConfiguration(1);
  await device.claimInterface(0);
  assert_true(device.configuration.interfaces[0].claimed);
  await device.releaseInterface(0);
  assert_false(device.configuration.interfaces[0].claimed);
  await device.releaseInterface(0);
  assert_false(device.configuration.interfaces[0].claimed);
  await device.close();
}, 'an interface can be released multiple times');

usb_test(async (t) => {
  let { device } = await getFakeDevice();
  await device.open();
  await device.selectConfiguration(1);
  return Promise.all([
    device.claimInterface(0),
    promise_rejects_dom(t, 'InvalidStateError', device.claimInterface(0)),
    promise_rejects_dom(t, 'InvalidStateError', device.releaseInterface(0)),
    promise_rejects_dom(t, 'InvalidStateError', device.open()),
    promise_rejects_dom(t, 'InvalidStateError', device.selectConfiguration(1)),
    promise_rejects_dom(t, 'InvalidStateError', device.reset()),
    promise_rejects_dom(
        t, 'InvalidStateError', device.selectAlternateInterface(0, 0)),
    promise_rejects_dom(t, 'InvalidStateError', device.controlTransferOut({
      requestType: 'standard',
      recipient: 'interface',
      request: 0x42,
      value: 0x1234,
      index: 0x0000,
    })),
    promise_rejects_dom(
        t, 'InvalidStateError',
        device.controlTransferOut(
            {
              requestType: 'standard',
              recipient: 'interface',
              request: 0x42,
              value: 0x1234,
              index: 0x0000,
            },
            new Uint8Array([1, 2, 3]))),
    promise_rejects_dom(
        t, 'InvalidStateError',
        device.controlTransferIn(
            {
              requestType: 'standard',
              recipient: 'interface',
              request: 0x42,
              value: 0x1234,
              index: 0x0000
            },
            0)),
    promise_rejects_dom(t, 'InvalidStateError', device.close()),
  ]);
}, 'device operations reject if an interface state change is in progress');

usb_test(async () => {
  let { device } = await getFakeDevice();
  await device.open();
  await device.selectConfiguration(1);
  await device.claimInterface(0);
  assert_true(device.configuration.interfaces[0].claimed);
  await device.close(0);
  assert_false(device.configuration.interfaces[0].claimed);
}, 'interfaces are released on close');

usb_test((t) => {
  return getFakeDevice().then(({device}) => {
    return device.open()
        .then(() => device.selectConfiguration(1))
        .then(() => Promise.all([
          promise_rejects_dom(t, 'NotFoundError', device.claimInterface(2)),
          promise_rejects_dom(t, 'NotFoundError', device.releaseInterface(2)),
        ]))
        .then(() => device.close());
  });
}, 'a non-existent interface cannot be claimed or released');

usb_test((t) => {
  return getFakeDevice().then(({device, fakeDevice}) => {
    return device.open()
        .then(() => device.selectConfiguration(1))
        .then(() => waitForDisconnect(fakeDevice))
        .then(
            () => promise_rejects_dom(
                t, 'NotFoundError', device.claimInterface(0)));
  });
}, 'claimInterface rejects when called on a disconnected device');

usb_test((t) => {
  return getFakeDevice().then(({device, fakeDevice}) => {
    return device.open()
        .then(() => device.selectConfiguration(1))
        .then(() => device.claimInterface(0))
        .then(() => waitForDisconnect(fakeDevice))
        .then(
            () => promise_rejects_dom(
                t, 'NotFoundError', device.releaseInterface(0)));
  });
}, 'releaseInterface rejects when called on a disconnected device');

usb_test(() => {
  return getFakeDevice().then(({ device }) => {
    return device.open()
      .then(() => device.selectConfiguration(2))
      .then(() => device.claimInterface(0))
      .then(() => device.selectAlternateInterface(0, 1))
      .then(() => device.close());
  });
}, 'can select an alternate interface');

usb_test(
    async () => {
      const {device} = await getFakeDevice();
      await device.open();
      await device.selectConfiguration(3);
      await device.claimInterface(2);
      await device.selectAlternateInterface(2, 0);
      await device.close();
    },
    'can select an alternate interface on a setting with non-sequential ' +
        'interface number');

usb_test(
    async () => {
      const {device} = await getFakeDevice();
      await device.open();
      await device.selectConfiguration(3);
      await device.claimInterface(0);
      await device.selectAlternateInterface(0, 2);
      await device.close();
    },
    'can select an alternate interface on a setting with non-sequential ' +
        'alternative setting value');

usb_test((t) => {
  return getFakeDevice().then(({device}) => {
    return device.open()
        .then(() => device.selectConfiguration(2))
        .then(() => device.claimInterface(0))
        .then(
            () => promise_rejects_dom(
                t, 'NotFoundError', device.selectAlternateInterface(0, 2)))
        .then(() => device.close());
  });
}, 'cannot select a non-existent alternate interface');

usb_test((t) => {
  return getFakeDevice().then(({device, fakeDevice}) => {
    return device.open()
        .then(() => device.selectConfiguration(2))
        .then(() => device.claimInterface(0))
        .then(() => waitForDisconnect(fakeDevice))
        .then(
            () => promise_rejects_dom(
                t, 'NotFoundError', device.selectAlternateInterface(0, 1)));
  });
}, 'selectAlternateInterface rejects when called on a disconnected device');

usb_test(async () => {
  let { device } = await getFakeDevice();
  let usbRequestTypes = ['standard', 'class', 'vendor'];
  let usbRecipients = ['device', 'interface', 'endpoint', 'other'];
  await device.open();
  await device.selectConfiguration(1);
  await device.claimInterface(0);
  await device.selectAlternateInterface(0, 0);
  for (const requestType of usbRequestTypes) {
    for (const recipient of usbRecipients) {
      let index = recipient === 'interface' ? 0x5600 : 0x5681;
      let result = await device.controlTransferIn({
        requestType: requestType,
        recipient: recipient,
        request: 0x42,
        value: 0x1234,
        index: index
      }, 7);
      assert_true(result instanceof USBInTransferResult);
      assert_equals(result.status, 'ok');
      assert_equals(result.data.byteLength, 7);
      assert_equals(result.data.getUint16(0), 0x07);
      assert_equals(result.data.getUint8(2), 0x42);
      assert_equals(result.data.getUint16(3), 0x1234);
      assert_equals(result.data.getUint16(5), index);
    }
  }
  await device.close();
}, 'can issue all types of IN control transfers');

usb_test(async () => {
  let { device } = await getFakeDevice();
  let usbRequestTypes = ['standard', 'class', 'vendor'];
  let usbRecipients = ['device', 'other'];
  await device.open();
  await Promise.all(usbRequestTypes.flatMap(requestType => {
    return usbRecipients.map(async recipient => {
      let result = await device.controlTransferIn({
        requestType: requestType,
        recipient: recipient,
        request: 0x42,
        value: 0x1234,
        index: 0x5678
      }, 7);
      assert_true(result instanceof USBInTransferResult);
      assert_equals(result.status, 'ok');
      assert_equals(result.data.byteLength, 7);
      assert_equals(result.data.getUint16(0), 0x07);
      assert_equals(result.data.getUint8(2), 0x42);
      assert_equals(result.data.getUint16(3), 0x1234);
      assert_equals(result.data.getUint16(5), 0x5678);
    });
  }));
  await device.close();
}, 'device-scope IN control transfers don\'t require configuration');

usb_test(async (t) => {
  let { device } = await getFakeDevice();
  let usbRequestTypes = ['standard', 'class', 'vendor'];
  let usbRecipients = ['interface', 'endpoint'];
  await device.open();
  await Promise.all(usbRequestTypes.flatMap(requestType => {
    return usbRecipients.map(recipient => {
      let index = recipient === 'interface' ? 0x5600 : 0x5681;
      return promise_rejects_dom(
          t, 'InvalidStateError',
          device.controlTransferIn(
              {
                requestType: requestType,
                recipient: recipient,
                request: 0x42,
                value: 0x1234,
                index: index
              },
              7));
    });
  }));
  await device.close();
}, 'interface-scope IN control transfers require configuration');

usb_test(async (t) => {
  let { device } = await getFakeDevice();
  let usbRequestTypes = ['standard', 'class', 'vendor'];
  let usbRecipients = ['interface', 'endpoint'];
  await device.open();
  await device.selectConfiguration(1);
  await Promise.all(usbRequestTypes.flatMap(requestType => {
    return [
      promise_rejects_dom(
          t, 'InvalidStateError',
          device.controlTransferIn(
              {
                requestType: requestType,
                recipient: 'interface',
                request: 0x42,
                value: 0x1234,
                index: 0x5600
              },
              7)),
      promise_rejects_dom(
          t, 'NotFoundError',
          device.controlTransferIn(
              {
                requestType: requestType,
                recipient: 'endpoint',
                request: 0x42,
                value: 0x1234,
                index: 0x5681
              },
              7))
    ];
  }));
  await device.close();
}, 'interface-scope IN control transfers require claiming the interface');

usb_test((t) => {
  return getFakeDevice().then(({device, fakeDevice}) => {
    return device.open()
        .then(() => device.selectConfiguration(1))
        .then(() => waitForDisconnect(fakeDevice))
        .then(
            () => promise_rejects_dom(
                t, 'NotFoundError',
                device.controlTransferIn(
                    {
                      requestType: 'vendor',
                      recipient: 'device',
                      request: 0x42,
                      value: 0x1234,
                      index: 0x5678
                    },
                    7)));
  });
}, 'controlTransferIn rejects when called on a disconnected device');

usb_test(async () => {
  let { device } = await getFakeDevice();
  let usbRequestTypes = ['standard', 'class', 'vendor'];
  let usbRecipients = ['device', 'interface', 'endpoint', 'other'];
  let dataArray = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
  let dataTypes = [dataArray, dataArray.buffer];
  await device.open();
  await device.selectConfiguration(1);
  await device.claimInterface(0);
  await device.selectAlternateInterface(0, 0);
  for (const requestType of usbRequestTypes) {
    for (const recipient of usbRecipients) {
      let index = recipient === 'interface' ? 0x5600 : 0x5681;
      let transferParams = {
        requestType: requestType,
        recipient: recipient,
        request: 0x42,
        value: 0x1234,
        index: index
      };
      for (const data of dataTypes) {
        let result = await device.controlTransferOut(transferParams, data);
        assert_true(result instanceof USBOutTransferResult);
        assert_equals(result.status, 'ok');
        assert_equals(result.bytesWritten, 8);
      }
      let result = await device.controlTransferOut(transferParams);
      assert_true(result instanceof USBOutTransferResult);
      assert_equals(result.status, 'ok');
    }
  }
  await device.close();
}, 'can issue all types of OUT control transfers');

usb_test(async () => {
  let { device } = await getFakeDevice();
  let usbRequestTypes = ['standard', 'class', 'vendor'];
  let usbRecipients = ['device', 'other'];
  let dataArray = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
  let dataTypes = [dataArray, dataArray.buffer];
  await device.open();
  await Promise.all(usbRequestTypes.flatMap(requestType => {
    return usbRecipients.flatMap(recipient => {
      let transferParams = {
        requestType: requestType,
        recipient: recipient,
        request: 0x42,
        value: 0x1234,
        index: 0x5678
      };
      return dataTypes.map(async data => {
        let result = await device.controlTransferOut(transferParams, data);
        assert_true(result instanceof USBOutTransferResult);
        assert_equals(result.status, 'ok');
        assert_equals(result.bytesWritten, 8);
      }).push((async () => {
        let result = await device.controlTransferOut(transferParams);
        assert_true(result instanceof USBOutTransferResult);
        assert_equals(result.status, 'ok');
      })());
    });
  }));
  await device.close();
}, 'device-scope OUT control transfers don\'t require configuration');

usb_test(async (t) => {
  let { device } = await getFakeDevice();
  let usbRequestTypes = ['standard', 'class', 'vendor'];
  let usbRecipients = ['interface', 'endpoint'];
  let dataArray = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
  let dataTypes = [dataArray, dataArray.buffer];
  await device.open();
  await Promise.all(usbRequestTypes.flatMap(requestType => {
    return usbRecipients.flatMap(recipient => {
      let index = recipient === 'interface' ? 0x5600 : 0x5681;
      let transferParams = {
        requestType: requestType,
        recipient: recipient,
        request: 0x42,
        value: 0x1234,
        index: index
      };
      return dataTypes
          .map(data => {
            return promise_rejects_dom(
                t, 'InvalidStateError',
                device.controlTransferOut(transferParams, data));
          })
          .push(promise_rejects_dom(
              t, 'InvalidStateError',
              device.controlTransferOut(transferParams)));
    });
  }));
  await device.close();
}, 'interface-scope OUT control transfers require configuration');

usb_test(async (t) => {
  let { device } = await getFakeDevice();
  let usbRequestTypes = ['standard', 'class', 'vendor'];
  let usbRecipients = ['interface', 'endpoint'];
  let dataArray = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
  let dataTypes = [dataArray, dataArray.buffer];
  await device.open();
  await device.selectConfiguration(1);
  await Promise.all(usbRequestTypes.flatMap(requestType => {
    return usbRecipients.flatMap(recipient => {
      let index = recipient === 'interface' ? 0x5600 : 0x5681;
      let error =
          recipient === 'interface' ? 'InvalidStateError' : 'NotFoundError';
      let transferParams = {
        requestType: requestType,
        recipient: recipient,
        request: 0x42,
        value: 0x1234,
        index: index
      };
      return dataTypes
          .map(data => {
            return promise_rejects_dom(
                t, error, device.controlTransferOut(transferParams, data));
          })
          .push(promise_rejects_dom(
              t, error, device.controlTransferOut(transferParams)));
    });
  }));
  await device.close();
}, 'interface-scope OUT control transfers an interface claim');

usb_test((t) => {
  return getFakeDevice().then(({device, fakeDevice}) => {
    return device.open()
        .then(() => device.selectConfiguration(1))
        .then(() => waitForDisconnect(fakeDevice))
        .then(
            () => promise_rejects_dom(
                t, 'NotFoundError',
                device.controlTransferOut(
                    {
                      requestType: 'vendor',
                      recipient: 'device',
                      request: 0x42,
                      value: 0x1234,
                      index: 0x5678
                    },
                    new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]))));
  });
}, 'controlTransferOut rejects when called on a disconnected device');

usb_test(async (t) => {
  let { device } = await getFakeDevice();
  await device.open();
  await device.selectConfiguration(1);
  await device.claimInterface(0);
  await Promise.all([
    promise_rejects_js(
        t, TypeError,
        device.controlTransferOut(
            {
              requestType: 'invalid',
              recipient: 'device',
              request: 0x42,
              value: 0x1234,
              index: 0x5678
            },
            new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]))),
    promise_rejects_js(
        t, TypeError,
        device.controlTransferIn(
            {
              requestType: 'invalid',
              recipient: 'device',
              request: 0x42,
              value: 0x1234,
              index: 0x5678
            },
            0)),
  ]);
  await device.close();
}, 'control transfers with a invalid request type reject');

usb_test(async (t) => {
  let { device } = await getFakeDevice();
  await device.open();
  await device.selectConfiguration(1);
  await device.claimInterface(0);
  await Promise.all([
    promise_rejects_js(
        t, TypeError,
        device.controlTransferOut(
            {
              requestType: 'vendor',
              recipient: 'invalid',
              request: 0x42,
              value: 0x1234,
              index: 0x5678
            },
            new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]))),
    promise_rejects_js(
        t, TypeError,
        device.controlTransferIn(
            {
              requestType: 'vendor',
              recipient: 'invalid',
              request: 0x42,
              value: 0x1234,
              index: 0x5678
            },
            0)),
  ]);
}, 'control transfers with a invalid recipient type reject');

usb_test(async (t) => {
  let { device } = await getFakeDevice();
  await device.open();
  await device.selectConfiguration(1);
  await device.claimInterface(0);
  await Promise.all([
    promise_rejects_dom(
        t, 'NotFoundError',
        device.controlTransferOut(
            {
              requestType: 'vendor',
              recipient: 'interface',
              request: 0x42,
              value: 0x1234,
              index: 0x0002  // Last byte of index is interface number.
            },
            new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]))),
    promise_rejects_dom(
        t, 'NotFoundError',
        device.controlTransferIn(
            {
              requestType: 'vendor',
              recipient: 'interface',
              request: 0x42,
              value: 0x1234,
              index: 0x0002  // Last byte of index is interface number.
            },
            0)),
  ]);
}, 'control transfers to a non-existant interface reject');

usb_test((t) => {
  return getFakeDevice().then(({ device }) => {
    let interfaceRequest = {
        requestType: 'vendor',
        recipient: 'interface',
        request: 0x42,
        value: 0x1234,
        index: 0x5600  // Last byte of index is interface number.
    };
    let endpointRequest = {
        requestType: 'vendor',
        recipient: 'endpoint',
        request: 0x42,
        value: 0x1234,
        index: 0x5681  // Last byte of index is endpoint address.
    };
    let data = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
    return device.open()
        .then(() => device.selectConfiguration(1))
        .then(() => Promise.all([
          promise_rejects_dom(
              t, 'InvalidStateError',
              device.controlTransferIn(interfaceRequest, 7)),
          promise_rejects_dom(
              t, 'NotFoundError', device.controlTransferIn(endpointRequest, 7)),
          promise_rejects_dom(
              t, 'InvalidStateError',
              device.controlTransferOut(interfaceRequest, data)),
          promise_rejects_dom(
              t, 'NotFoundError',
              device.controlTransferOut(endpointRequest, data)),
        ]))
        .then(() => device.claimInterface(0))
        .then(() => Promise.all([
          device.controlTransferIn(interfaceRequest, 7).then(result => {
            assert_true(result instanceof USBInTransferResult);
            assert_equals(result.status, 'ok');
            assert_equals(result.data.byteLength, 7);
            assert_equals(result.data.getUint16(0), 0x07);
            assert_equals(result.data.getUint8(2), 0x42);
            assert_equals(result.data.getUint16(3), 0x1234);
            assert_equals(result.data.getUint16(5), 0x5600);
          }),
          device.controlTransferIn(endpointRequest, 7).then(result => {
            assert_true(result instanceof USBInTransferResult);
            assert_equals(result.status, 'ok');
            assert_equals(result.data.byteLength, 7);
            assert_equals(result.data.getUint16(0), 0x07);
            assert_equals(result.data.getUint8(2), 0x42);
            assert_equals(result.data.getUint16(3), 0x1234);
            assert_equals(result.data.getUint16(5), 0x5681);
          }),
          device.controlTransferOut(interfaceRequest, data),
          device.controlTransferOut(endpointRequest, data),
        ]))
        .then(() => device.close());
  });
}, 'requests to interfaces and endpoint require an interface claim');

usb_test(async () => {
  const { device } = await getFakeDevice();
  await device.open();
  await device.selectConfiguration(1);
  await device.claimInterface(0);

  const transfer_params = {
      requestType: 'vendor',
      recipient: 'device',
      request: 0,
      value: 0,
      index: 0
  };

  try {
    const array_buffer = new ArrayBuffer(64 * 8);
    const result =
        await device.controlTransferOut(transfer_params, array_buffer);
    assert_equals(result.status, 'ok');

    detachBuffer(array_buffer);
    await device.controlTransferOut(transfer_params, array_buffer);
    assert_unreached();
  } catch (e) {
    assert_equals(e.code, DOMException.INVALID_STATE_ERR);
  }

  try {
    const typed_array = new Uint8Array(64 * 8);
    const result =
        await device.controlTransferOut(transfer_params, typed_array);
    assert_equals(result.status, 'ok');

    detachBuffer(typed_array.buffer);
    await device.controlTransferOut(transfer_params, typed_array);
    assert_unreached();
  } catch (e) {
    assert_equals(e.code, DOMException.INVALID_STATE_ERR);
  }
}, 'controlTransferOut rejects if called with a detached buffer');

usb_test(() => {
  return getFakeDevice().then(({ device }) => {
    return device.open()
      .then(() => device.selectConfiguration(1))
      .then(() => device.claimInterface(0))
      .then(() => device.clearHalt('in', 1))
      .then(() => device.close());
  });
}, 'can clear a halt condition');

usb_test((t) => {
  return getFakeDevice(t).then(({device, fakeDevice}) => {
    return device.open()
        .then(() => device.selectConfiguration(1))
        .then(() => device.claimInterface(0))
        .then(() => waitForDisconnect(fakeDevice))
        .then(
            () => promise_rejects_dom(
                t, 'NotFoundError', device.clearHalt('in', 1)));
  });
}, 'clearHalt rejects when called on a disconnected device');

usb_test((t) => {
  return getFakeDevice().then(({ device }) => {
    let data = new DataView(new ArrayBuffer(1024));
    for (let i = 0; i < 1024; ++i)
      data.setUint8(i, i & 0xff);
    return device.open()
        .then(() => device.selectConfiguration(1))
        .then(() => device.claimInterface(0))
        .then(() => Promise.all([
          promise_rejects_dom(
              t, 'NotFoundError', device.transferIn(2, 8)),  // Unclaimed
          promise_rejects_dom(
              t, 'NotFoundError', device.transferIn(3, 8)),  // Non-existent
          promise_rejects_dom(t, 'IndexSizeError', device.transferIn(16, 8)),
          promise_rejects_dom(
              t, 'NotFoundError', device.transferOut(2, data)),  // Unclaimed
          promise_rejects_dom(
              t, 'NotFoundError', device.transferOut(3, data)),  // Non-existent
          promise_rejects_dom(
              t, 'IndexSizeError', device.transferOut(16, data)),
        ]));
  });
}, 'transfers to unavailable endpoints are rejected');

usb_test(() => {
  return getFakeDevice().then(({ device }) => {
    return device.open()
      .then(() => device.selectConfiguration(1))
      .then(() => device.claimInterface(0))
      .then(() => device.transferIn(1, 8))
      .then(result => {
        assert_true(result instanceof USBInTransferResult);
        assert_equals(result.status, 'ok');
        assert_equals(result.data.byteLength, 8);
        for (let i = 0; i < 8; ++i)
          assert_equals(result.data.getUint8(i), i, 'mismatch at byte ' + i);
        return device.close();
      });
  });
}, 'can issue IN interrupt transfer');

usb_test(() => {
  return getFakeDevice().then(({ device }) => {
    return device.open()
      .then(() => device.selectConfiguration(1))
      .then(() => device.claimInterface(1))
      .then(() => device.transferIn(2, 1024))
      .then(result => {
        assert_true(result instanceof USBInTransferResult);
        assert_equals(result.status, 'ok');
        assert_equals(result.data.byteLength, 1024);
        for (let i = 0; i < 1024; ++i)
          assert_equals(result.data.getUint8(i), i & 0xff,
                        'mismatch at byte ' + i);
        return device.close();
      });
  });
}, 'can issue IN bulk transfer');

usb_test((t) => {
  return getFakeDevice().then(({device, fakeDevice}) => {
    return device.open()
        .then(() => device.selectConfiguration(1))
        .then(() => device.claimInterface(1))
        .then(() => waitForDisconnect(fakeDevice))
        .then(
            () => promise_rejects_dom(
                t, 'NotFoundError', device.transferIn(2, 1024)));
  });
}, 'transferIn rejects if called on a disconnected device');

usb_test(() => {
  return getFakeDevice().then(({ device }) => {
    return device.open()
      .then(() => device.selectConfiguration(1))
      .then(() => device.claimInterface(1))
      .then(() => {
        let data = new DataView(new ArrayBuffer(1024));
        for (let i = 0; i < 1024; ++i)
          data.setUint8(i, i & 0xff);
        return device.transferOut(2, data);
      })
      .then(result => {
        assert_true(result instanceof USBOutTransferResult);
        assert_equals(result.status, 'ok');
        assert_equals(result.bytesWritten, 1024);
        return device.close();
      });
  });
}, 'can issue OUT bulk transfer');

usb_test((t) => {
  return getFakeDevice().then(({ device, fakeDevice }) => {
    return device.open()
      .then(() => device.selectConfiguration(1))
      .then(() => device.claimInterface(1))
      .then(() => {
        let data = new DataView(new ArrayBuffer(1024));
        for (let i = 0; i < 1024; ++i)
          data.setUint8(i, i & 0xff);
        return waitForDisconnect(fakeDevice)
            .then(
                () => promise_rejects_dom(
                    t, 'NotFoundError', device.transferOut(2, data)));
      });
  });
}, 'transferOut rejects if called on a disconnected device');

usb_test(async () => {
  const { device } = await getFakeDevice();
  await device.open();
  await device.selectConfiguration(1);
  await device.claimInterface(1);


  try {
    const array_buffer = new ArrayBuffer(64 * 8);
    const result = await device.transferOut(2, array_buffer);
    assert_equals(result.status, 'ok');

    detachBuffer(array_buffer);
    await device.transferOut(2, array_buffer);
    assert_unreached();
  } catch (e) {
    assert_equals(e.code, DOMException.INVALID_STATE_ERR);
  }

  try {
    const typed_array = new Uint8Array(64 * 8);
    const result = await device.transferOut(2, typed_array);
    assert_equals(result.status, 'ok');

    detachBuffer(typed_array.buffer);
    await device.transferOut(2, typed_array);
    assert_unreached();
  } catch (e) {
    assert_equals(e.code, DOMException.INVALID_STATE_ERR);
  }
}, 'transferOut rejects if called with a detached buffer');

usb_test(() => {
  return getFakeDevice().then(({ device }) => {
    return device.open()
      .then(() => device.selectConfiguration(2))
      .then(() => device.claimInterface(0))
      .then(() => device.selectAlternateInterface(0, 1))
      .then(() => device.isochronousTransferIn(
          1, [64, 64, 64, 64, 64, 64, 64, 64]))
      .then(result => {
        assert_true(result instanceof USBIsochronousInTransferResult);
        assert_equals(result.data.byteLength, 64 * 8, 'buffer size');
        assert_equals(result.packets.length, 8, 'number of packets');
        let byteOffset = 0;
        for (let i = 0; i < result.packets.length; ++i) {
          assert_true(
              result.packets[i] instanceof USBIsochronousInTransferPacket);
          assert_equals(result.packets[i].status, 'ok');
          assert_equals(result.packets[i].data.byteLength, 64);
          assert_equals(result.packets[i].data.buffer, result.data.buffer);
          assert_equals(result.packets[i].data.byteOffset, byteOffset);
          for (let j = 0; j < 64; ++j)
            assert_equals(result.packets[i].data.getUint8(j), j & 0xff,
                          'mismatch at byte ' + j + ' of packet ' + i);
          byteOffset += result.packets[i].data.byteLength;
        }
        return device.close();
      });
  });
}, 'can issue IN isochronous transfer');

usb_test((t) => {
  return getFakeDevice().then(({device, fakeDevice}) => {
    return device.open()
        .then(() => device.selectConfiguration(2))
        .then(() => device.claimInterface(0))
        .then(() => device.selectAlternateInterface(0, 1))
        .then(() => waitForDisconnect(fakeDevice))
        .then(
            () => promise_rejects_dom(
                t, 'NotFoundError',
                device.isochronousTransferIn(
                    1, [64, 64, 64, 64, 64, 64, 64, 64])));
  });
}, 'isochronousTransferIn rejects when called on a disconnected device');

usb_test(() => {
  return getFakeDevice().then(({ device }) => {
    return device.open()
      .then(() => device.selectConfiguration(2))
      .then(() => device.claimInterface(0))
      .then(() => device.selectAlternateInterface(0, 1))
      .then(() => {
        let data = new DataView(new ArrayBuffer(64 * 8));
        for (let i = 0; i < 8; ++i) {
          for (let j = 0; j < 64; ++j)
            data.setUint8(i * j, j & 0xff);
        }
        return device.isochronousTransferOut(
            1, data, [64, 64, 64, 64, 64, 64, 64, 64]);
      })
      .then(result => {
        assert_true(result instanceof USBIsochronousOutTransferResult);
        assert_equals(result.packets.length, 8, 'number of packets');
        let byteOffset = 0;
        for (let i = 0; i < result.packets.length; ++i) {
          assert_true(
              result.packets[i] instanceof USBIsochronousOutTransferPacket);
          assert_equals(result.packets[i].status, 'ok');
          assert_equals(result.packets[i].bytesWritten, 64);
        }
        return device.close();
      });
  });
}, 'can issue OUT isochronous transfer');

usb_test((t) => {
  return getFakeDevice().then(({ device, fakeDevice }) => {
    return device.open()
      .then(() => device.selectConfiguration(2))
      .then(() => device.claimInterface(0))
      .then(() => device.selectAlternateInterface(0, 1))
      .then(() => {
        let data = new DataView(new ArrayBuffer(64 * 8));
        for (let i = 0; i < 8; ++i) {
          for (let j = 0; j < 64; ++j)
            data.setUint8(i * j, j & 0xff);
        }
        return waitForDisconnect(fakeDevice)
            .then(
                () => promise_rejects_dom(
                    t, 'NotFoundError',
                    device.isochronousTransferOut(
                        1, data, [64, 64, 64, 64, 64, 64, 64, 64])));
      });
  });
}, 'isochronousTransferOut rejects when called on a disconnected device');

usb_test(async () => {
  const { device } = await getFakeDevice();
  await device.open();
  await device.selectConfiguration(2);
  await device.claimInterface(0);
  await device.selectAlternateInterface(0, 1);


  try {
    const array_buffer = new ArrayBuffer(64 * 8);
    const result = await device.isochronousTransferOut(
        1, array_buffer, [64, 64, 64, 64, 64, 64, 64, 64]);
    for (let i = 0; i < result.packets.length; ++i)
      assert_equals(result.packets[i].status, 'ok');

    detachBuffer(array_buffer);
    await device.isochronousTransferOut(
        1, array_buffer, [64, 64, 64, 64, 64, 64, 64, 64]);
    assert_unreached();
  } catch (e) {
    assert_equals(e.code, DOMException.INVALID_STATE_ERR);
  }

  try {
    const typed_array = new Uint8Array(64 * 8);
    const result = await device.isochronousTransferOut(
        1, typed_array, [64, 64, 64, 64, 64, 64, 64, 64]);
    for (let i = 0; i < result.packets.length; ++i)
      assert_equals(result.packets[i].status, 'ok');

    detachBuffer(typed_array.buffer);
    await device.isochronousTransferOut(
        1, typed_array, [64, 64, 64, 64, 64, 64, 64, 64]);
    assert_unreached();
  } catch (e) {
    assert_equals(e.code, DOMException.INVALID_STATE_ERR);
  }
}, 'isochronousTransferOut rejects when called with a detached buffer');

usb_test(() => {
  return getFakeDevice().then(({ device }) => {
    return device.open().then(() => device.reset()).then(() => device.close());
  });
}, 'can reset the device');

usb_test((t) => {
  return getFakeDevice().then(({device, fakeDevice}) => {
    return device.open()
        .then(() => waitForDisconnect(fakeDevice))
        .then(() => promise_rejects_dom(t, 'NotFoundError', device.reset()));
  });
}, 'resetDevice rejects when called on a disconnected device');
