Commit fae44482 authored by Ken Rockot's avatar Ken Rockot Committed by Chromium LUCI CQ

Migrate WebUSB WPT to Mojo JS modules

Bug: 1004256
Change-Id: Iaaf8e601a7f3e400bd7aff5b60e8586e7adb43a2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2616519Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarMichael Moss <mmoss@chromium.org>
Auto-Submit: Ken Rockot <rockot@google.com>
Commit-Queue: Ken Rockot <rockot@google.com>
Cr-Commit-Position: refs/heads/master@{#841569}
parent 14aaa5eb
...@@ -443,17 +443,17 @@ FILES = [ ...@@ -443,17 +443,17 @@ FILES = [
}, },
# MojoJS support data (WebUSB): # MojoJS support data (WebUSB):
{ {
'filename': 'gen/url/mojom/url.mojom.js', 'filename': 'gen/url/mojom/url.mojom.m.js',
'buildtype': ['dev', 'official'], 'buildtype': ['dev', 'official'],
'archive': 'mojojs.zip', 'archive': 'mojojs.zip',
}, },
{ {
'filename': 'gen/services/device/public/mojom/usb_*.mojom.js', 'filename': 'gen/services/device/public/mojom/usb_*.mojom.m.js',
'buildtype': ['dev', 'official'], 'buildtype': ['dev', 'official'],
'archive': 'mojojs.zip', 'archive': 'mojojs.zip',
}, },
{ {
'filename': 'gen/third_party/blink/public/mojom/usb/web_usb_service.mojom.js', 'filename': 'gen/third_party/blink/public/mojom/usb/web_usb_service.mojom.m.js',
'buildtype': ['dev', 'official'], 'buildtype': ['dev', 'official'],
'archive': 'mojojs.zip', 'archive': 'mojojs.zip',
}, },
......
...@@ -723,12 +723,12 @@ MISSING DEPENDENCY: generic-sensor/resources/generic-sensor-helpers.js ...@@ -723,12 +723,12 @@ MISSING DEPENDENCY: generic-sensor/resources/generic-sensor-helpers.js
MISSING DEPENDENCY: idle-detection/resources/idle-detection-helper.js MISSING DEPENDENCY: idle-detection/resources/idle-detection-helper.js
MISSING DEPENDENCY: mediacapture-image/resources/imagecapture-helpers.js MISSING DEPENDENCY: mediacapture-image/resources/imagecapture-helpers.js
MISSING DEPENDENCY: orientation-event/resources/orientation-event-helpers.js MISSING DEPENDENCY: orientation-event/resources/orientation-event-helpers.js
MISSING DEPENDENCY: resources/chromium/webusb-test.js
MISSING DEPENDENCY: resources/test-only-api.js MISSING DEPENDENCY: resources/test-only-api.js
MISSING DEPENDENCY: screen_enumeration/resources/screenenumeration-helpers.js MISSING DEPENDENCY: screen_enumeration/resources/screenenumeration-helpers.js
MISSING DEPENDENCY: serial/resources/automation.js MISSING DEPENDENCY: serial/resources/automation.js
MISSING DEPENDENCY: shape-detection/resources/shapedetection-helpers.js MISSING DEPENDENCY: shape-detection/resources/shapedetection-helpers.js
MISSING DEPENDENCY: web-nfc/resources/nfc-helpers.js MISSING DEPENDENCY: web-nfc/resources/nfc-helpers.js
MISSING DEPENDENCY: webusb/resources/usb-helpers.js
MISSING DEPENDENCY: webxr/resources/webxr_util.js MISSING DEPENDENCY: webxr/resources/webxr_util.js
# Tests that are false positives for using Ahem as a system font # Tests that are false positives for using Ahem as a system font
......
...@@ -16,6 +16,19 @@ let internal = { ...@@ -16,6 +16,19 @@ let internal = {
messagePort: null, messagePort: null,
}; };
let mojom = {};
async function loadMojomDefinitions() {
const deviceMojom =
await import('/gen/services/device/public/mojom/usb_device.mojom.m.js');
const serviceMojom = await import(
'/gen/third_party/blink/public/mojom/usb/web_usb_service.mojom.m.js');
return {
...deviceMojom,
...serviceMojom,
};
}
function getMessagePort(target) { function getMessagePort(target) {
return new Promise(resolve => { return new Promise(resolve => {
target.addEventListener('message', messageEvent => { target.addEventListener('message', messageEvent => {
...@@ -93,29 +106,29 @@ function fakeDeviceInitToDeviceInfo(guid, init) { ...@@ -93,29 +106,29 @@ function fakeDeviceInitToDeviceInfo(guid, init) {
var endpointInfo = { var endpointInfo = {
endpointNumber: endpoint.endpointNumber, endpointNumber: endpoint.endpointNumber,
packetSize: endpoint.packetSize, packetSize: endpoint.packetSize,
synchronizationType: device.mojom.UsbSynchronizationType.NONE, synchronizationType: mojom.UsbSynchronizationType.NONE,
usageType: device.mojom.UsbUsageType.DATA, usageType: mojom.UsbUsageType.DATA,
pollingInterval: 0, pollingInterval: 0,
extraData: new Uint8Array() extraData: new Uint8Array()
}; };
switch (endpoint.direction) { switch (endpoint.direction) {
case "in": case "in":
endpointInfo.direction = device.mojom.UsbTransferDirection.INBOUND; endpointInfo.direction = mojom.UsbTransferDirection.INBOUND;
break; break;
case "out": case "out":
endpointInfo.direction = device.mojom.UsbTransferDirection.OUTBOUND; endpointInfo.direction = mojom.UsbTransferDirection.OUTBOUND;
break; break;
} }
switch (endpoint.type) { switch (endpoint.type) {
case "bulk": case "bulk":
endpointInfo.type = device.mojom.UsbTransferType.BULK; endpointInfo.type = mojom.UsbTransferType.BULK;
break; break;
case "interrupt": case "interrupt":
endpointInfo.type = device.mojom.UsbTransferType.INTERRUPT; endpointInfo.type = mojom.UsbTransferType.INTERRUPT;
break; break;
case "isochronous": case "isochronous":
endpointInfo.type = device.mojom.UsbTransferType.ISOCHRONOUS; endpointInfo.type = mojom.UsbTransferType.ISOCHRONOUS;
break; break;
} }
alternateInfo.endpoints.push(endpointInfo); alternateInfo.endpoints.push(endpointInfo);
}); });
...@@ -173,7 +186,7 @@ class FakeDevice { ...@@ -173,7 +186,7 @@ class FakeDevice {
open() { open() {
assert_false(this.opened_); assert_false(this.opened_);
this.opened_ = true; this.opened_ = true;
return Promise.resolve({ error: device.mojom.UsbOpenDeviceError.OK }); return Promise.resolve({error: mojom.UsbOpenDeviceError.OK});
} }
close() { close() {
...@@ -244,36 +257,35 @@ class FakeDevice { ...@@ -244,36 +257,35 @@ class FakeDevice {
async controlTransferIn(params, length, timeout) { async controlTransferIn(params, length, timeout) {
assert_true(this.opened_); assert_true(this.opened_);
if ((params.recipient == device.mojom.UsbControlTransferRecipient.INTERFACE || if ((params.recipient == mojom.UsbControlTransferRecipient.INTERFACE ||
params.recipient == device.mojom.UsbControlTransferRecipient.ENDPOINT) && params.recipient == mojom.UsbControlTransferRecipient.ENDPOINT) &&
this.currentConfiguration_ == null) { this.currentConfiguration_ == null) {
return { return {
status: device.mojom.UsbTransferStatus.PERMISSION_DENIED, status: mojom.UsbTransferStatus.PERMISSION_DENIED,
}; };
} }
return { return {
status: device.mojom.UsbTransferStatus.OK, status: mojom.UsbTransferStatus.OK,
data: [length >> 8, length & 0xff, params.request, params.value >> 8, data: [
params.value & 0xff, params.index >> 8, params.index & 0xff] length >> 8, length & 0xff, params.request, params.value >> 8,
params.value & 0xff, params.index >> 8, params.index & 0xff
]
}; };
} }
async controlTransferOut(params, data, timeout) { async controlTransferOut(params, data, timeout) {
assert_true(this.opened_); assert_true(this.opened_);
if ((params.recipient == device.mojom.UsbControlTransferRecipient.INTERFACE || if ((params.recipient == mojom.UsbControlTransferRecipient.INTERFACE ||
params.recipient == device.mojom.UsbControlTransferRecipient.ENDPOINT) && params.recipient == mojom.UsbControlTransferRecipient.ENDPOINT) &&
this.currentConfiguration_ == null) { this.currentConfiguration_ == null) {
return { return {
status: device.mojom.UsbTransferStatus.PERMISSION_DENIED, status: mojom.UsbTransferStatus.PERMISSION_DENIED,
}; };
} }
return { return {status: mojom.UsbTransferStatus.OK, bytesWritten: data.byteLength};
status: device.mojom.UsbTransferStatus.OK,
bytesWritten: data.byteLength
};
} }
genericTransferIn(endpointNumber, length, timeout) { genericTransferIn(endpointNumber, length, timeout) {
...@@ -283,20 +295,15 @@ class FakeDevice { ...@@ -283,20 +295,15 @@ class FakeDevice {
let data = new Array(length); let data = new Array(length);
for (let i = 0; i < length; ++i) for (let i = 0; i < length; ++i)
data[i] = i & 0xff; data[i] = i & 0xff;
return Promise.resolve({ return Promise.resolve({status: mojom.UsbTransferStatus.OK, data: data});
status: device.mojom.UsbTransferStatus.OK,
data: data
});
} }
genericTransferOut(endpointNumber, data, timeout) { genericTransferOut(endpointNumber, data, timeout) {
assert_true(this.opened_); assert_true(this.opened_);
assert_false(this.currentConfiguration_ == null, 'device configured'); assert_false(this.currentConfiguration_ == null, 'device configured');
// TODO(reillyg): Assert that endpoint is valid. // TODO(reillyg): Assert that endpoint is valid.
return Promise.resolve({ return Promise.resolve(
status: device.mojom.UsbTransferStatus.OK, {status: mojom.UsbTransferStatus.OK, bytesWritten: data.byteLength});
bytesWritten: data.byteLength
});
} }
isochronousTransferIn(endpointNumber, packetLengths, timeout) { isochronousTransferIn(endpointNumber, packetLengths, timeout) {
...@@ -312,7 +319,7 @@ class FakeDevice { ...@@ -312,7 +319,7 @@ class FakeDevice {
packets[i] = { packets[i] = {
length: packetLengths[i], length: packetLengths[i],
transferredLength: packetLengths[i], transferredLength: packetLengths[i],
status: device.mojom.UsbTransferStatus.OK status: mojom.UsbTransferStatus.OK
}; };
} }
return Promise.resolve({ data: data, packets: packets }); return Promise.resolve({ data: data, packets: packets });
...@@ -327,7 +334,7 @@ class FakeDevice { ...@@ -327,7 +334,7 @@ class FakeDevice {
packets[i] = { packets[i] = {
length: packetLengths[i], length: packetLengths[i],
transferredLength: packetLengths[i], transferredLength: packetLengths[i],
status: device.mojom.UsbTransferStatus.OK status: mojom.UsbTransferStatus.OK
}; };
} }
return Promise.resolve({ packets: packets }); return Promise.resolve({ packets: packets });
...@@ -336,7 +343,7 @@ class FakeDevice { ...@@ -336,7 +343,7 @@ class FakeDevice {
class FakeWebUsbService { class FakeWebUsbService {
constructor() { constructor() {
this.bindingSet_ = new mojo.BindingSet(blink.mojom.WebUsbService); this.receiver_ = new mojom.WebUsbServiceReceiver(this);
this.devices_ = new Map(); this.devices_ = new Map();
this.devicesByGuid_ = new Map(); this.devicesByGuid_ = new Map();
this.client_ = null; this.client_ = null;
...@@ -344,7 +351,7 @@ class FakeWebUsbService { ...@@ -344,7 +351,7 @@ class FakeWebUsbService {
} }
addBinding(handle) { addBinding(handle) {
this.bindingSet_.addBinding(this, handle); this.receiver_.$.bindHandle(handle);
} }
addDevice(fakeDevice, info) { addDevice(fakeDevice, info) {
...@@ -352,7 +359,7 @@ class FakeWebUsbService { ...@@ -352,7 +359,7 @@ class FakeWebUsbService {
fakeDevice: fakeDevice, fakeDevice: fakeDevice,
guid: (this.nextGuid_++).toString(), guid: (this.nextGuid_++).toString(),
info: info, info: info,
bindingArray: [] receivers: [],
}; };
this.devices_.set(fakeDevice, device); this.devices_.set(fakeDevice, device);
this.devicesByGuid_.set(device.guid, device); this.devicesByGuid_.set(device.guid, device);
...@@ -365,8 +372,8 @@ class FakeWebUsbService { ...@@ -365,8 +372,8 @@ class FakeWebUsbService {
if (!device) if (!device)
throw new Error('Cannot remove unknown device.'); throw new Error('Cannot remove unknown device.');
for (var binding of device.bindingArray) for (const receiver of device.receivers)
binding.close(); receiver.$.close();
this.devices_.delete(device.fakeDevice); this.devices_.delete(device.fakeDevice);
this.devicesByGuid_.delete(device.guid); this.devicesByGuid_.delete(device.guid);
if (this.client_) { if (this.client_) {
...@@ -377,8 +384,8 @@ class FakeWebUsbService { ...@@ -377,8 +384,8 @@ class FakeWebUsbService {
removeAllDevices() { removeAllDevices() {
this.devices_.forEach(device => { this.devices_.forEach(device => {
for (var binding of device.bindingArray) for (const receiver of device.receivers)
binding.close(); receiver.$.close();
this.client_.onDeviceRemoved( this.client_.onDeviceRemoved(
fakeDeviceInitToDeviceInfo(device.guid, device.info)); fakeDeviceInitToDeviceInfo(device.guid, device.info));
}); });
...@@ -397,17 +404,16 @@ class FakeWebUsbService { ...@@ -397,17 +404,16 @@ class FakeWebUsbService {
getDevice(guid, request) { getDevice(guid, request) {
let retrievedDevice = this.devicesByGuid_.get(guid); let retrievedDevice = this.devicesByGuid_.get(guid);
if (retrievedDevice) { if (retrievedDevice) {
let binding = new mojo.Binding( const receiver =
device.mojom.UsbDevice, new mojom.UsbDeviceReceiver(new FakeDevice(retrievedDevice.info));
new FakeDevice(retrievedDevice.info), receiver.$.bindHandle(request.handle);
request); receiver.onConnectionError.addListener(() => {
binding.setConnectionErrorHandler(() => {
if (retrievedDevice.fakeDevice.onclose) if (retrievedDevice.fakeDevice.onclose)
retrievedDevice.fakeDevice.onclose(); retrievedDevice.fakeDevice.onclose();
}); });
retrievedDevice.bindingArray.push(binding); retrievedDevice.receivers.push(receiver);
} else { } else {
request.close(); request.handle.close();
} }
} }
...@@ -422,8 +428,8 @@ class FakeWebUsbService { ...@@ -422,8 +428,8 @@ class FakeWebUsbService {
}); });
} }
setClient(clientInfo) { setClient(client) {
this.client_ = new device.mojom.UsbDeviceManagerClientAssociatedPtr(clientInfo); this.client_ = client;
} }
} }
...@@ -474,9 +480,10 @@ class USBTest { ...@@ -474,9 +480,10 @@ class USBTest {
getMessagePort(window); getMessagePort(window);
} }
mojom = await loadMojomDefinitions();
internal.webUsbService = new FakeWebUsbService(); internal.webUsbService = new FakeWebUsbService();
internal.webUsbServiceInterceptor = internal.webUsbServiceInterceptor =
new MojoInterfaceInterceptor(blink.mojom.WebUsbService.name); new MojoInterfaceInterceptor(mojom.WebUsbService.$interfaceName);
internal.webUsbServiceInterceptor.oninterfacerequest = internal.webUsbServiceInterceptor.oninterfacerequest =
e => internal.webUsbService.addBinding(e.handle); e => internal.webUsbService.addBinding(e.handle);
internal.webUsbServiceInterceptor.start(); internal.webUsbServiceInterceptor.start();
...@@ -498,7 +505,7 @@ class USBTest { ...@@ -498,7 +505,7 @@ class USBTest {
return new Promise(resolve => { return new Promise(resolve => {
internal.messagePort.onmessage = channelEvent => { internal.messagePort.onmessage = channelEvent => {
switch (channelEvent.data.type) { switch (channelEvent.data.type) {
case blink.mojom.WebUsbService.name: case mojom.WebUsbService.$interfaceName:
internal.webUsbService.addBinding(channelEvent.data.handle); internal.webUsbService.addBinding(channelEvent.data.handle);
break; break;
case 'Complete': case 'Complete':
...@@ -507,10 +514,11 @@ class USBTest { ...@@ -507,10 +514,11 @@ class USBTest {
} }
}; };
internal.messagePort.postMessage({ internal.messagePort.postMessage({
type: 'Attach' , type: 'Attach',
interfaces: [ interfaces: [
blink.mojom.WebUsbService.name, mojom.WebUsbService.$interfaceName,
]}); ]
});
}); });
}); });
} }
......
...@@ -16,28 +16,12 @@ ...@@ -16,28 +16,12 @@
} }
})(); })();
// This function is shared between blink/web_tests/usb and external/wpt/webusb.
// Only include "/gen/" paths here, which are available in both places.
async function loadChromiumResources() {
const chromiumResources = [
'/gen/mojo/public/mojom/base/big_buffer.mojom.js',
'/gen/mojo/public/mojom/base/string16.mojom.js',
'/gen/url/mojom/url.mojom.js',
'/gen/services/device/public/mojom/usb_device.mojom.js',
'/gen/services/device/public/mojom/usb_enumeration_options.mojom.js',
'/gen/services/device/public/mojom/usb_manager_client.mojom.js',
'/gen/third_party/blink/public/mojom/usb/web_usb_service.mojom.js',
];
await loadMojoResources(chromiumResources);
}
function usb_test(func, name, properties) { function usb_test(func, name, properties) {
promise_test(async () => { promise_test(async () => {
assert_implements(navigator.usb, 'missing navigator.usb'); assert_implements(navigator.usb, 'missing navigator.usb');
if (navigator.usb.test === undefined) { if (navigator.usb.test === undefined) {
// Try loading a polyfill for the WebUSB Testing API. // Try loading a polyfill for the WebUSB Testing API.
if (isChromiumBased) { if (isChromiumBased) {
await loadChromiumResources();
await loadScript('/resources/chromium/webusb-test.js'); await loadScript('/resources/chromium/webusb-test.js');
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment