Closed thegecko closed 2 years ago
We'd consider this policies on a case by case basis
We'd consider this policies on a case by case basis
Thanks, I've reworded the title and description of this request to focus on interest in exposing WebUSB in webviews.
Have you tested to see if this would work on the web? Webview contents are run inside iframes from a different origin than the main editor page. Even if we enable the policy on the iframe itself, I don't know that webUSB would work
You can try this using a local build of VS Code, modifying the iframe to have the correct permissions, and then running yarn web
to start a browser with a test workspace
Have you tested to see if this would work on the web? ...You can try this using a local build of VS Code
Many thanks for the pointers, @mjbvz. I have tested this change locally as you describe and can confirm that updating the allow
permissions as follows:
element.setAttribute('allow', 'clipboard-read; clipboard-write; usb;');
Successfully enables webviews to invoke WebUSB
features:
I assume the feature to be implemented would be to control this setting from the webviewView.webview.options
object?
Perhaps WebHID
and WebSerial
should also be considered?
Yes please. WebHID, WebSerial would be excellent additions.
These are the final pieces of the puzzle to open up embedded development to the masses.
It seems you can achieve it via web extensions, see https://github.com/gitpod-io/gitpod/issues/5814#issuecomment-937526878
It seems you can achieve it via web extensions, see gitpod-io/gitpod#5814 (comment)
Not quite?
https://github.com/gitpod-io/gitpod/issues/5814#issuecomment-938401052
workbench.experimental.requestUsbDevice
) that you can use on web to request USB access. This lets your extension code use the webUSB apis directly:Here's how it works:
To get permissions to access a usb device ( this is usb.requestDevice()
) your extension must call this command instead of trying to call navigator.usb.requestDevice
directly
This is needed because your extension is running in a worker thread which cannot request permissions itself
After the user selects some devices and finished the permissions flow, your extension code can then call navigator.usb.getDevices
to access the selected devices
This command is only enabled on web and only works in Chrome/Edge. Please give it a try and let us know if you have any feedback
The new command relies on Chrome's permission delegation feature. While implementing it, I also realized that permission delegation makes enabling webUSB inside of our webviews too risky without a lot more thought.
The root problem is that once one iframe (webview) on a page request usb access, all the other usb enable iframes embedded into that page can also access that device without showing any prompts. It also means that if our top level page gets access to a usb device, all usb enabled iframes on the page can then also access that device. Instead we want all webviews to have to request permissions individually and then only be able to access their own pool of devices
I've opened a chromium issue about this behavior
Great news we have some progress on this!
I'll try it when I find some spare cycles, but have some initial questions:
Both of my concerns have been addressed in https://github.com/microsoft/vscode/pull/152257 👍
FYI, PRs now open to expose similar functionality for WebSerial
and WebHID
using the same pattern:
Experimental support has now been added, I believe this issue can be closed.
I tried this on insiders.vscode.dev using the webview-sample as a starting point
First, I added the following to the webview:
setInterval(() => {
navigator.usb.getDevices().then(devices => {
devices.forEach(device => {
vscode.postMessage({
command: 'alert',
text: `Got product: ${device.productName}`
});
});
})
}, 10_000);
Then I made the "do refactor" command request device access:
context.subscriptions.push(
vscode.commands.registerCommand('catCoding.doRefactor', () => {
vscode.commands.executeCommand('workbench.experimental.requestUsbDevice');
})
);
While I saw the permissions prompt and granted access to my iphone, the request from the webview continued to error:
Are there steps I'm missing?
The Web-* interfaces are only enabled in the extensionHost web worker, so I wouldn't expect the navigator access to work directly in webviews.
You should be able to access devices in the normal extension code, I'll try to find some time to create a demo.
BTW @connor4312 how are you testing on insiders.vscode.dev? it seems the recommended approach is not currently possible due to the localtunnel server being unavailable.
Please see this repo for a demo web extension which can request device authorisation through a webview and also list authorised devices:
I'd be interested to understand whether there is appetite to add control of enabling WebUSB access in web extensions and webviews:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy/usb
With VSCode going online through projects such as codespaces, there are strong use cases for accessing broader Web APIs and in this case, the ability to interact with devices attached to the user's machine. This could enable scenarios such as debugging of connected devices, which is already possible in the desktop version of VSCode.
I'd be happy to implement the feature, but would be keen to understand whether it would be accepted.