Skip to content

Commit d7b95cb

Browse files
committed
Make WebUSB work on WebWorkers
1 parent dde4fed commit d7b95cb

File tree

5 files changed

+30
-12
lines changed

5 files changed

+30
-12
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ web-sys = { version = "*", features = [
6565
"UsbOutTransferResult",
6666
"UsbDirection",
6767
"UsbConnectionEvent",
68+
"WorkerGlobalScope",
69+
"WorkerNavigator",
6870
] }
6971
wasm-bindgen-futures = { version = "*" }
7072

src/platform/webusb/device.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{sync::Arc, time::Duration};
1+
use std::{io::Error, sync::Arc, time::Duration};
22

33
use wasm_bindgen_futures::{js_sys::Array, wasm_bindgen::JsCast, JsFuture};
44
use web_sys::{
@@ -9,7 +9,7 @@ use web_sys::{
99
use crate::{
1010
descriptors::{validate_config_descriptor, DESCRIPTOR_TYPE_CONFIGURATION},
1111
transfer::{Control, EndpointType, TransferError, TransferHandle},
12-
DeviceInfo, Error,
12+
DeviceInfo,
1313
};
1414

1515
use super::web_to_nusb_status;
@@ -22,9 +22,7 @@ pub(crate) struct WebusbDevice {
2222

2323
impl WebusbDevice {
2424
pub(crate) async fn from_device_info(d: &DeviceInfo) -> Result<Arc<WebusbDevice>, Error> {
25-
let window = web_sys::window().unwrap();
26-
let navigator = window.navigator();
27-
let usb = navigator.usb();
25+
let usb = super::usb()?;
2826
let devices = JsFuture::from(usb.get_devices()).await.unwrap();
2927
let devices: Array = JsCast::unchecked_from_js(devices);
3028

src/platform/webusb/enumeration.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ use crate::{
99

1010
pub async fn list_devices() -> Result<impl Iterator<Item = DeviceInfo>, Error> {
1111
async fn inner() -> Result<Vec<DeviceInfo>, Error> {
12-
let window = web_sys::window()
13-
.ok_or_else(|| Error::other("WebUSB is not available on this platform"))?;
14-
let navigator = window.navigator();
15-
let usb = navigator.usb();
12+
let usb = super::usb()?;
1613
let devices = JsFuture::from(usb.get_devices())
1714
.await
1815
.map_err(|e| Error::other(format!("WebUSB devices could not be listed: {e:?}")))?;

src/platform/webusb/hotplug.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ pub(crate) struct WebusbHotplugWatch {
2424

2525
impl WebusbHotplugWatch {
2626
pub fn new() -> Result<Self, Error> {
27-
let window = web_sys::window().unwrap();
28-
let navigator = window.navigator();
29-
let usb = navigator.usb();
27+
let usb = super::usb()?;
3028
let waker = Arc::new(AtomicWaker::new());
3129
let (sender, receiver) = channel();
3230
{

src/platform/webusb/mod.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ mod enumeration;
33
mod hotplug;
44
mod transfer;
55

6+
use std::io::Error;
7+
68
pub(crate) use transfer::TransferData;
79

810
pub use enumeration::{list_buses, list_devices};
@@ -11,9 +13,14 @@ pub(crate) use device::WebusbDevice as Device;
1113
pub(crate) use device::WebusbInterface as Interface;
1214
pub(crate) use hotplug::WebusbHotplugWatch as HotplugWatch;
1315

16+
use web_sys::js_sys;
1417
use web_sys::js_sys::Reflect;
18+
use web_sys::wasm_bindgen::JsCast;
1519
use web_sys::wasm_bindgen::JsValue;
20+
use web_sys::Usb;
1621
use web_sys::UsbDevice;
22+
use web_sys::Window;
23+
use web_sys::WorkerGlobalScope;
1724

1825
use crate::transfer::TransferError;
1926

@@ -54,3 +61,19 @@ pub(crate) fn web_to_nusb_status(status: web_sys::UsbTransferStatus) -> Result<(
5461
_ => unreachable!(),
5562
}
5663
}
64+
65+
pub(crate) fn usb() -> Result<Usb, Error> {
66+
let window = js_sys::global().dyn_into::<Window>().ok();
67+
68+
if let Some(window) = window {
69+
return Ok(window.navigator().usb());
70+
}
71+
72+
let wgs = js_sys::global().dyn_into::<WorkerGlobalScope>().ok();
73+
74+
if let Some(wgs) = wgs {
75+
return Ok(wgs.navigator().usb());
76+
}
77+
78+
Err(Error::other("WebUSB is not available on this platform"))
79+
}

0 commit comments

Comments
 (0)