Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider exposing WebUSB functionality in extensions #116761

Closed
thegecko opened this issue Feb 16, 2021 · 20 comments
Closed

Consider exposing WebUSB functionality in extensions #116761

thegecko opened this issue Feb 16, 2021 · 20 comments
Assignees
Labels
api author-verification-requested Issues potentially verifiable by issue author feature-request Request for new features or functionality verification-needed Verification of issue is requested verified Verification succeeded webview Webview issues
Milestone

Comments

@thegecko
Copy link
Contributor

thegecko commented Feb 16, 2021

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.

@mjbvz
Copy link
Collaborator

mjbvz commented Feb 16, 2021

We'd consider this policies on a case by case basis

@thegecko thegecko changed the title Consider exposing control of some feature-policy settings in webviews Consider exposing control of WebUSB feature-policy in webviews Feb 17, 2021
@thegecko
Copy link
Contributor Author

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.

@mjbvz mjbvz added api feature-request Request for new features or functionality webview Webview issues labels Feb 17, 2021
@mjbvz
Copy link
Collaborator

mjbvz commented Feb 17, 2021

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

@thegecko
Copy link
Contributor Author

thegecko commented Feb 19, 2021

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:

Screenshot 2021-02-19 at 13 40 55

I assume the feature to be implemented would be to control this setting from the webviewView.webview.options object?

@thegecko
Copy link
Contributor Author

thegecko commented Apr 3, 2021

Perhaps WebHID and WebSerial should also be considered?

@0Grit
Copy link

0Grit commented Sep 6, 2021

Yes please. WebHID, WebSerial would be excellent additions.

These are the final pieces of the puzzle to open up embedded development to the masses.

@akosyakov
Copy link
Contributor

It seems you can achieve it via web extensions, see gitpod-io/gitpod#5814 (comment)

@0Grit
Copy link

0Grit commented Dec 10, 2021

It seems you can achieve it via web extensions, see gitpod-io/gitpod#5814 (comment)

Not quite?

gitpod-io/gitpod#5814 (comment)

@thegecko thegecko changed the title Consider exposing control of WebUSB feature-policy in webviews Consider exposing WebUSB functionality in extensions Mar 5, 2022
@mjbvz
Copy link
Collaborator

mjbvz commented Jun 15, 2022

#151795 introduces an experimental command (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:

  1. 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

  2. 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

@thegecko
Copy link
Contributor Author

Great news we have some progress on this!

I'll try it when I find some spare cycles, but have some initial questions:

  • I assume further updates to this would include the ability to specify the filters so the developer can restrict devices being requested to those of interest?
  • Using this model, how can a developer know which device the user selected? In a scenario where multiple devices are connected, it's common to select or highlight the one just requested

@thegecko
Copy link
Contributor Author

Both of my concerns have been addressed in #152257 👍

@thegecko
Copy link
Contributor Author

FYI, PRs now open to expose similar functionality for WebSerial and WebHID using the same pattern:

@thegecko
Copy link
Contributor Author

Experimental support has now been added, I believe this issue can be closed.

@mjbvz mjbvz added the author-verification-requested Issues potentially verifiable by issue author label Jun 28, 2022
@rzhao271 rzhao271 added the verification-needed Verification of issue is requested label Jun 28, 2022
@connor4312 connor4312 added the verified Verification succeeded label Jun 29, 2022
@connor4312
Copy link
Member

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:

image

Are there steps I'm missing?

@connor4312 connor4312 added verification-steps-needed Steps to verify are needed for verification and removed verified Verification succeeded labels Jun 29, 2022
@thegecko
Copy link
Contributor Author

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.

@thegecko
Copy link
Contributor Author

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.

@thegecko
Copy link
Contributor Author

Please see this repo for a demo web extension which can request device authorisation through a webview and also list authorised devices:

https://github.com/thegecko/webusb-web-extension

@connor4312 connor4312 added verified Verification succeeded and removed verification-steps-needed Steps to verify are needed for verification labels Jun 30, 2022
@connor4312
Copy link
Member

The only reason localtunnel.me was used was to provide the extension over https, which I do locally with the serve CLI and a self-signed cert I made with mkcert.

@github-actions github-actions bot locked and limited conversation to collaborators Aug 5, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api author-verification-requested Issues potentially verifiable by issue author feature-request Request for new features or functionality verification-needed Verification of issue is requested verified Verification succeeded webview Webview issues
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants
@thegecko @connor4312 @akosyakov @rzhao271 @mjbvz @0Grit and others