Skip to content

Commit 9a22f98

Browse files
authored
Update to the USB/HID Container Starter (#115)
* Updated usb example * Added logic to pass values from browser to Here Container * Updated versioning in example links to reflect manifest versions and updated usb example
1 parent 30f8da4 commit 9a22f98

18 files changed

+1217
-127
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Changelog
2+
3+
## October 2025
4+
5+
- [detect-usb-devices](./how-to/detect-usb-devices/README.md) - Updated Readme to provide more details around configuration and a code sample. Updated example so that it acts as a tool which can be run locally or through live launch which lets you connect to a device, get the required vendorId and productId and launch a window that can connect and log out information.

README.md

Lines changed: 15 additions & 15 deletions
Large diffs are not rendered by default.

how-to/detect-usb-devices/README.md

Lines changed: 213 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## How it Works
44

5-
Using a combination of the manifest file and WebUSB APIs, we can search for and detect connected USB devices inside of a container application.
5+
Using a combination of the manifest file and WebUSB/WebHID APIs, we permission and get connected USB devices inside of a container application.
66

77
## Get Started
88

@@ -36,14 +36,219 @@ npm run client
3636

3737
### What you will see
3838

39-
1. An Platform Window with a button that leads you to documentation around WebUSB API usage, along with another button that should detect a plugged in device and display it in a list below.
39+
#### Main App View (app.html)
4040

41-
## A note about this example
41+
- A view loaded into a platform window.
42+
- It contains a button to open up the HERE related documentation in a new window.
43+
- It contains a button to open up a window in your default browser (Chrome/Edge) called device-identifier.html
44+
- Form elements to say whether you are targeting a USB or HID Device, the VendorID and the ProductID of the device you are looking to test against (these details can be return by the device-identifier.html page).
45+
- It contains a button that will take the data from the form elements to create a new window with the correct permissions to allow a connection to the specified device (device-connector.html).
4246

43-
This is an example of how to use OpenFin APIs to configure OpenFin Container. Its purpose is to provide an example and suggestions. **DO NOT** assume that it contains production-ready code. Please use this as a guide and provide feedback. Thanks!
47+
![App View](./assets/connect-to-device-app.png)
4448

45-
There are 3 things you should know when trying to detect and use USB devices (Printers, etc..) alongside your Container:
49+
#### Device Identifier (device-identifier.html)
4650

47-
1. Make sure to add the necessary permissions to the manifest file, specifically, the WebAPI and Devices sections.
48-
2. Use best practices with the API by reading more [here](https://developer.mozilla.org/en-US/docs/Web/API/WebUSB_API).
49-
3. If you have any additional questions, please email [Here.io Support](mailto:[email protected]).
51+
Launched from the main window into your default desktop browser (e.g. Chrome/Edge). This page provides two buttons so you can pick a USB or HID device. On selection the results will be presented so that you can manually add the VendorID and ProductID on the main page or you can use a button to return to the pass the details back to the form elements within the platform.
52+
53+
![Device Identifier](./assets/connect-to-device-identifier.png)
54+
55+
#### Device Connector (device-connector.html)
56+
57+
Launched from the main window using the form details related to the target device. The permissions of the launched window will include the correct details for the connection and the window will show a code section showing some example code and a log section that shows what's happening. There is an option to open a connection to the device through a button.
58+
59+
![Device Connector](./assets/connect-to-device-connector.png)
60+
61+
## Example Loom
62+
63+
<https://www.loom.com/share/63d31b30454e478fbc415724fb28ec82?sid=1480153e-c2a3-4208-98b9-1b2c45df554b>
64+
65+
## Required Permissions
66+
67+
Permissions need to be defined in the window/view that wants to connect to a USB/HID device. This lets developers connect to the device without requiring user interaction.
68+
69+
This can be done in a number of places and must include the webAPIs permissions to access usb and hid devices as well as the list of devices you are allowing by providing their vendor and product Ids:
70+
71+
### Manifest - startup_app
72+
73+
If you have a classic manifest where you are using a startup_app definition and you want the entry (main) window to be able to connect to a device then you can have the following defined:
74+
75+
```json
76+
{
77+
"startup_app": {
78+
"permissions": {
79+
"webAPIs": ["hid", "usb"],
80+
"devices": [
81+
{
82+
"vendorId": 3034,
83+
"productId": 21783
84+
}
85+
]
86+
}
87+
}
88+
}
89+
```
90+
91+
### Manifest - platform
92+
93+
If you have a platform app with a custom platform provider window and you want the platform provider to connect then you will need to define the rules inside of the platform section of your manifest. \*\*Please note if any child window/view needs access to usb/hid devices then the platform should define the permission (it doesn't need to specify the devices but the permission should be available at the root level).
94+
95+
```json
96+
{
97+
"platform": {
98+
"permissions": {
99+
"webAPIs": ["hid", "usb"],
100+
"devices": [
101+
{
102+
"vendorId": 3034,
103+
"productId": 21783
104+
}
105+
]
106+
}
107+
}
108+
}
109+
```
110+
111+
#### Window Level
112+
113+
You can either set the window permissions for all windows through Default Window Options (if you are using a platform manifest setup) or for a specific window through Window Options when you launch it.
114+
115+
##### Default Window Options
116+
117+
```json
118+
{
119+
"platform": {
120+
"permissions": {
121+
"webAPIs": ["hid", "usb"]
122+
},
123+
"defaultWindowOptions": {
124+
"permissions": {
125+
"webAPIs": ["hid", "usb"],
126+
"devices": [
127+
{
128+
"vendorId": 3034,
129+
"productId": 21783
130+
}
131+
]
132+
}
133+
}
134+
}
135+
}
136+
```
137+
138+
##### Window Options
139+
140+
If you only want a specific window to have this permission then you can specify the permission as part of the window options when launching it (this is the approach used by the sample when it is launching a window targeting a specific device).
141+
142+
```json
143+
{
144+
"url": "The url to load alongside other settings",
145+
"permissions": {
146+
"webAPIs": ["hid", "usb"],
147+
"devices": [
148+
{
149+
"vendorId": 3034,
150+
"productId": 21783
151+
}
152+
]
153+
}
154+
}
155+
```
156+
157+
#### View Level
158+
159+
If you are using a platform manifest and views then you can either set the view permissions for all views through Default View Options or for a specific view through View Options when you launch it.
160+
161+
##### Default View Options
162+
163+
```json
164+
{
165+
"platform": {
166+
"permissions": {
167+
"webAPIs": ["hid", "usb"]
168+
},
169+
"defaultViewOptions": {
170+
"permissions": {
171+
"webAPIs": ["hid", "usb"],
172+
"devices": [
173+
{
174+
"vendorId": 3034,
175+
"productId": 21783
176+
}
177+
]
178+
}
179+
}
180+
}
181+
}
182+
```
183+
184+
##### View Options
185+
186+
```json
187+
{
188+
"permissions": {
189+
"webAPIs": ["hid", "usb"],
190+
"devices": [
191+
{
192+
"vendorId": 3034,
193+
"productId": 21783
194+
}
195+
]
196+
}
197+
}
198+
```
199+
200+
##### Domain Settings
201+
202+
If your platform is loading or navigating to a number of different domains and you only want your specific domain to be able to connect to the device then we would recommend using Domain Settings. If you are already familiar with domain settings we generally recommend them over window/view level settings as they ensure only your domain can utilize a permission.
203+
204+
<https://resources.here.io/docs/javascript/stable/interfaces/OpenFin.DomainSettings.html>
205+
206+
## Code Example
207+
208+
You do not need to request the device as the permissions have already given access.
209+
210+
You can get the devices and then open the one you wish using standard JavaScript APIs. The example below is using the HID API but the sample will provide code snippets for USB or HID when run.
211+
212+
```js
213+
// Listen for device connection and disconnection events
214+
navigator.hid.addEventListener('disconnect', (event) => {
215+
console.log('HID disconnected: ' + event.device.productName);
216+
});
217+
navigator.hid.addEventListener('connect', (event) => {
218+
console.log('HID connected: ' + event.device.productName);
219+
});
220+
221+
// Getting HID devices
222+
// You don't need to call requestDevice as the device has already been given permissions through the manifest/window/view permission settings. You can call getDevices to interact with the device.
223+
const devices = await navigator.hid.getDevices();
224+
console.log('Found ' + devices.length + ' HID devices.');
225+
devices.forEach((device, index) => {
226+
console.log(
227+
'Device ' +
228+
(index + 1) +
229+
': Product Name: ' +
230+
device.productName +
231+
', Vendor ID: ' +
232+
device.vendorId +
233+
', Product ID: ' +
234+
device.productId
235+
);
236+
});
237+
238+
// Selecting the first device (if any)
239+
const device = devices.length > 0 ? devices[0] : null;
240+
241+
// Opening the device
242+
if (device) {
243+
await device.open();
244+
console.log('Device opened:', device.productName);
245+
// Add event listeners for input reports
246+
device.addEventListener('inputreport', (event) => {
247+
// perform custom logic here. The below is just an example.
248+
const data = new Uint8Array(event.data.buffer);
249+
console.log('Input report received:', data);
250+
});
251+
} else {
252+
console.log('No device selected');
253+
}
254+
```
142 KB
Loading
434 KB
Loading
180 KB
Loading

0 commit comments

Comments
 (0)