Skip to content

Commit 4c0399f

Browse files
committed
Add Android USB support
1 parent caad22d commit 4c0399f

File tree

16 files changed

+623
-57
lines changed

16 files changed

+623
-57
lines changed

android/app/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ repositories {
2828
flatDir{
2929
dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
3030
}
31+
google()
32+
mavenCentral()
33+
maven { url 'https://jitpack.io' }
3134
}
3235

3336
dependencies {

android/app/capacitor.build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ android {
99

1010
apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
1111
dependencies {
12-
12+
implementation project(':capacitor-plugin-usb-serial')
1313

1414
}
1515

android/app/src/main/AndroidManifest.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@
2222
<category android:name="android.intent.category.LAUNCHER" />
2323
</intent-filter>
2424

25+
<intent-filter>
26+
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
27+
</intent-filter>
28+
29+
<meta-data
30+
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
31+
android:resource="@xml/device_filter" />
32+
2533
</activity>
2634

2735
<provider
@@ -38,4 +46,7 @@
3846
<!-- Permissions -->
3947

4048
<uses-permission android:name="android.permission.INTERNET" />
49+
50+
<!-- USB Host feature -->
51+
<uses-feature android:name="android.hardware.usb.host" android:required="true" />
4152
</manifest>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<!-- USB device filters for Betaflight-compatible devices -->
4+
5+
<!-- FT232R USB UART -->
6+
<usb-device vendor-id="1027" product-id="24577" />
7+
8+
<!-- STM32 devices -->
9+
<usb-device vendor-id="1155" product-id="12886" /> <!-- STM32 in HID mode -->
10+
<usb-device vendor-id="1155" product-id="14158" /> <!-- STLink Virtual COM Port (NUCLEO boards) -->
11+
<usb-device vendor-id="1155" product-id="22336" /> <!-- STM Electronics Virtual COM Port -->
12+
<usb-device vendor-id="1155" product-id="57105" /> <!-- STM Device in DFU Mode -->
13+
14+
<!-- CP210x devices -->
15+
<usb-device vendor-id="4292" product-id="60000" />
16+
<usb-device vendor-id="4292" product-id="60001" />
17+
<usb-device vendor-id="4292" product-id="60002" />
18+
19+
<!-- GD32 devices -->
20+
<usb-device vendor-id="10473" product-id="394" /> <!-- GD32 VCP -->
21+
<usb-device vendor-id="10473" product-id="393" /> <!-- GD32 DFU Bootloader -->
22+
23+
<!-- AT32 devices -->
24+
<usb-device vendor-id="11836" product-id="22336" /> <!-- AT32 VCP -->
25+
<usb-device vendor-id="11836" product-id="57105" /> <!-- AT32F435 DFU Bootloader -->
26+
27+
<!-- APM32 devices -->
28+
<usb-device vendor-id="12619" product-id="22336" /> <!-- APM32 VCP -->
29+
<usb-device vendor-id="12619" product-id="262" /> <!-- APM32 DFU Bootloader -->
30+
31+
<!-- Raspberry Pi Pico devices -->
32+
<usb-device vendor-id="11914" product-id="9" /> <!-- Raspberry Pi Pico VCP -->
33+
<usb-device vendor-id="11914" product-id="15" /> <!-- Raspberry Pi Pico in Bootloader mode -->
34+
</resources>

android/capacitor.settings.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
22
include ':capacitor-android'
33
project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor')
4+
5+
include ':capacitor-plugin-usb-serial'
6+
project(':capacitor-plugin-usb-serial').projectDir = new File('../node_modules/capacitor-plugin-usb-serial/android')

android/gradlew

100644100755
File mode changed.

android/settings.gradle

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,12 @@ include ':app'
22
include ':capacitor-cordova-android-plugins'
33
project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/')
44

5+
dependencyResolutionManagement {
6+
repositories {
7+
google()
8+
mavenCentral()
9+
maven { url 'https://jitpack.io' }
10+
}
11+
}
12+
513
apply from: 'capacitor.settings.gradle'

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"@capacitor/core": "^7.0.1",
4646
"@fortawesome/fontawesome-free": "^6.5.2",
4747
"@vitejs/plugin-vue": "^6.0.1",
48+
"capacitor-plugin-usb-serial": "^0.0.6",
4849
"crypto-es": "^2.1.0",
4950
"d3": "^7.9.0",
5051
"djv": "^2.1.4",

src/js/gui.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import MSP from "./msp";
33
import Switchery from "switchery-latest";
44
import tippy from "tippy.js";
55
import $ from "jquery";
6-
import { getOS } from "./utils/checkBrowserCompatibility";
6+
import { getOS } from "./utils/checkCompatibility";
77

88
const TABS = {};
99

src/js/port_handler.js

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import { serial } from "./serial.js";
44
import WEBUSBDFU from "./protocols/webusbdfu";
55
import { reactive } from "vue";
66
import {
7-
checkBrowserCompatibility,
8-
checkWebBluetoothSupport,
9-
checkWebSerialSupport,
10-
checkWebUSBSupport,
11-
} from "./utils/checkBrowserCompatibility.js";
7+
checkCompatibility,
8+
checkBluetoothSupport,
9+
checkSerialSupport,
10+
checkUsbSupport,
11+
} from "./utils/checkCompatibility.js";
1212

1313
const DEFAULT_PORT = "noselection";
1414
const DEFAULT_BAUDS = 115200;
@@ -34,11 +34,11 @@ const PortHandler = new (function () {
3434
this.dfuAvailable = false;
3535
this.portAvailable = false;
3636

37-
checkBrowserCompatibility();
37+
checkCompatibility();
3838

39-
this.showBluetoothOption = checkWebBluetoothSupport();
40-
this.showSerialOption = checkWebSerialSupport();
41-
this.showUsbOption = checkWebUSBSupport();
39+
this.showBluetoothOption = checkBluetoothSupport();
40+
this.showSerialOption = checkSerialSupport();
41+
this.showUsbOption = checkUsbSupport();
4242

4343
console.log(`${this.logHead} Bluetooth available: ${this.showBluetoothOption}`);
4444
console.log(`${this.logHead} Serial available: ${this.showSerialOption}`);
@@ -51,7 +51,7 @@ const PortHandler = new (function () {
5151

5252
PortHandler.initialize = function () {
5353
EventBus.$on("ports-input:request-permission-bluetooth", () => this.requestDevicePermission("webbluetooth"));
54-
EventBus.$on("ports-input:request-permission-serial", () => this.requestDevicePermission("webserial"));
54+
EventBus.$on("ports-input:request-permission-serial", () => this.requestDevicePermission("serial"));
5555
EventBus.$on("ports-input:request-permission-usb", () => this.requestDevicePermission("usb"));
5656
EventBus.$on("ports-input:change", this.onChangeSelectedPort.bind(this));
5757

@@ -62,7 +62,7 @@ PortHandler.initialize = function () {
6262
if (detail?.path?.startsWith("bluetooth")) {
6363
this.handleDeviceAdded(detail, "webbluetooth");
6464
} else {
65-
this.handleDeviceAdded(detail, "webserial");
65+
this.handleDeviceAdded(detail, "serial");
6666
}
6767
});
6868

@@ -81,7 +81,7 @@ PortHandler.initialize = function () {
8181
PortHandler.refreshAllDeviceLists = async function () {
8282
// Update all device lists in parallel
8383
return Promise.all([
84-
this.updateDeviceList("webserial"),
84+
this.updateDeviceList("serial"),
8585
this.updateDeviceList("webbluetooth"),
8686
this.updateDeviceList("usb"),
8787
]).then(() => {
@@ -112,7 +112,7 @@ PortHandler.removedSerialDevice = function (device) {
112112
if (!devicePath) {
113113
console.warn(`${this.logHead} Device removal event missing path information`, device);
114114
// Still update ports, but don't try to use the undefined path
115-
this.updateDeviceList("webserial").then(() => {
115+
this.updateDeviceList("serial").then(() => {
116116
this.selectActivePort();
117117
});
118118
return;
@@ -121,7 +121,7 @@ PortHandler.removedSerialDevice = function (device) {
121121
// Update the appropriate ports list based on the device type
122122
const updatePromise = devicePath.startsWith("bluetooth")
123123
? this.updateDeviceList("webbluetooth")
124-
: this.updateDeviceList("webserial");
124+
: this.updateDeviceList("serial");
125125

126126
const wasSelectedPort = this.portPicker.selectedPort === devicePath;
127127

@@ -274,7 +274,7 @@ PortHandler.handleDeviceAdded = function (device, deviceType) {
274274

275275
// Update the appropriate device list
276276
const updatePromise =
277-
deviceType === "webbluetooth" ? this.updateDeviceList("webbluetooth") : this.updateDeviceList("webserial");
277+
deviceType === "webbluetooth" ? this.updateDeviceList("webbluetooth") : this.updateDeviceList("serial");
278278

279279
updatePromise.then(() => {
280280
const selectedPort = this.selectActivePort(device);
@@ -305,9 +305,9 @@ PortHandler.updateDeviceList = async function (deviceType) {
305305
ports = await WEBUSBDFU.getDevices();
306306
}
307307
break;
308-
case "webserial":
308+
case "serial":
309309
if (this.showSerialOption) {
310-
ports = await serial.getDevices("webserial");
310+
ports = await serial.getDevices("serial");
311311
}
312312
break;
313313
default:
@@ -330,7 +330,7 @@ PortHandler.updateDeviceList = async function (deviceType) {
330330
this.currentUsbPorts = [...orderedPorts];
331331
console.log(`${this.logHead} Found DFU port(s)`, orderedPorts);
332332
break;
333-
case "webserial":
333+
case "serial":
334334
this.portAvailable = orderedPorts.length > 0;
335335
this.currentSerialPorts = [...orderedPorts];
336336
console.log(`${this.logHead} Found serial port(s)`, orderedPorts);

0 commit comments

Comments
 (0)