0

I am working on a Chrome Extension which will save specific resource to my Oculus Quest directly via WebUsb.

The problem is, I find the navigator.usb.requestDevice is not exist in service worker.

My plan is to maintain a adb connection between extension service worker and my Android device, so that when I click to download specific url, the extension will send an event to the service-worker, which will download the content and send it to my Android device.

My question is, how to make requestDevice work in service-worker, or do I have to create adb connection in contentScript instead of running in background?

enter image description here

Update:

I have try chrome.windows.create and it doesn't work. It is supposed to have a choose device show up in the address bar but the window created by service worker doesn't have one, so it is always report No device selected

enter image description here

asked Feb 9, 2025 at 9:25
2
  • Use the offscreen document. Commented Feb 9, 2025 at 9:48
  • @woxxom Sounds like it's worth a try, thanks. Commented Feb 9, 2025 at 16:10

2 Answers 2

1

requestDevice() cannot be called from a Service Worker because it has to show the permissions prompt UI (there are probably solutions to this, but they introduce additional challenges so it's the reason why it's currently disallowed).

For your use case, I think you have two options:

  1. In the Service Worker you can call navigator.usb.getDevices() to get a list of all the USB devices your extension has permission to access. If the device is already there you can perform the transfer in the background using the Service Worker. If not you need to call chrome.windows.create() to open a pop-up and request permission before the Service Worker can continue.

  2. Always call chrome.windows.create() to open a pop-up as part of transferring the file to the device, and use the pop-up to display progress in addition to needing it for the occasional permission prompt.

While an offscreen document, as suggested by one of the comments, can call requestDevice(), it will always throw an exception because the document is not visible.

answered Feb 10, 2025 at 1:50
Sign up to request clarification or add additional context in comments.

Comments

1

Thanks to Reilly's answer I have figured out a solution.

The key point is to create a normal window and handle the WebUSB in it, either offscreen, popup or panel window won't work as device selected menu won't be displayed and end up with No device selected.

And here is the key snippet of this solution

function createPopupAndSend(message: DownloadEvent) {
 chrome.windows.create({
 url: chrome.runtime.getURL(new URL("popup.html", import.meta.url).pathname),
 type: "normal",
 width: 600,
 height: 500,
 }, (newWindow) => {
 if (newWindow && newWindow.id !== undefined) {
 popupWindowId = newWindow.id;
 // Delay sending the message to give the popup time to load.
 setTimeout(() => {
 chrome.runtime.sendMessage(message);
 }, 500);
 }
 });
}
answered Feb 10, 2025 at 16:43

1 Comment

@woxxom It's not action popup. chrome.windows.create with type: popup doesn't work, it has to be type normal.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.