-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Patch manifest #4687
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
base: tauri
Are you sure you want to change the base?
Patch manifest #4687
Changes from 10 commits
fc31a5e
ae221c4
b6b31db
74a3266
983a9cf
c2163bd
0533869
a801f59
cadf39f
eb441f4
8c93e03
b1c3154
0a60f3e
2eb9aaa
cd6aa1f
2f2e9ab
e9c511e
3d13b6e
d71a7c1
04b8256
99642e8
aa9ddc8
8d87c20
37fb1b6
6d79317
a826b93
4a32b85
b85212b
792d918
735ac48
1d19205
9416e32
1331237
4435a99
bb84552
90cecf7
83122fc
7e03458
b7f391a
0a0bf83
62f9c41
05bc006
5ec9332
cb3680a
5f31190
a93186b
8e779cd
72173cf
56f041f
4dfd15e
c19e84c
bf62596
220037c
0e4c4c7
6dea4b3
7e5ce52
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| name: Test Android Manifest Patch | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
|
|
||
| jobs: | ||
| test-patch: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v5 | ||
|
|
||
| - name: Setup Node | ||
| uses: actions/setup-node@v5 | ||
| with: | ||
| node-version-file: '.nvmrc' | ||
| cache: 'yarn' | ||
|
|
||
| - name: Install dependencies | ||
| run: yarn install --frozen-lockfile | ||
|
|
||
| - name: Setup Java 21 | ||
| uses: actions/setup-java@v4 | ||
| with: | ||
| distribution: 'temurin' | ||
| java-version: '21' | ||
|
|
||
| - name: Setup Android SDK | ||
| uses: android-actions/setup-android@v3 | ||
|
|
||
| - name: Install Rust | ||
| uses: dtolnay/rust-toolchain@stable | ||
|
|
||
| - name: Install Rust Android targets | ||
| run: | | ||
| rustup target add aarch64-linux-android | ||
| rustup target add armv7-linux-androideabi | ||
| rustup target add i686-linux-android | ||
| rustup target add x86_64-linux-android | ||
|
|
||
| - name: Build web assets (Vite) | ||
| run: yarn build | ||
|
|
||
| - name: Initialize Tauri Android project | ||
| run: yarn tauri android init --ci | ||
|
|
||
| - name: Show generated manifest BEFORE patch | ||
| run: | | ||
| echo "=== MANIFEST BEFORE PATCH ===" | ||
| cat src-tauri/gen/android/app/src/main/AndroidManifest.xml || echo "Manifest not found" | ||
| echo "" | ||
| echo "=== APP BUILD.GRADLE.KTS BEFORE PATCH ===" | ||
| cat src-tauri/gen/android/app/build.gradle.kts || echo "build.gradle.kts not found" | ||
|
|
||
| - name: Patch Android manifest for USB support | ||
| run: bash scripts/patch-android-manifest.sh | ||
|
|
||
| - name: Show generated files AFTER patch | ||
| run: | | ||
| echo "=== MANIFEST AFTER PATCH ===" | ||
| cat src-tauri/gen/android/app/src/main/AndroidManifest.xml | ||
| echo "" | ||
| echo "=== DEVICE FILTER ===" | ||
| cat src-tauri/gen/android/app/src/main/res/xml/device_filter.xml || echo "device_filter.xml not found" | ||
| echo "" | ||
| echo "=== APP BUILD.GRADLE.KTS AFTER PATCH ===" | ||
| cat src-tauri/gen/android/app/build.gradle.kts | ||
| echo "" | ||
| echo "=== Checking for USB permissions ===" | ||
| grep -i "usb" src-tauri/gen/android/app/src/main/AndroidManifest.xml || echo "No USB found in manifest" | ||
| echo "" | ||
| echo "=== Checking for usb-serial dependency ===" | ||
| grep -i "usb-serial" src-tauri/gen/android/app/build.gradle.kts || echo "No usb-serial dependency found" | ||
|
|
||
| - name: Ensure JitPack repository | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| FILE="src-tauri/gen/android/build.gradle.kts" | ||
| if [ -f "$FILE" ]; then | ||
| echo "=== ROOT BUILD.GRADLE.KTS BEFORE JITPACK ===" | ||
| cat "$FILE" | ||
| echo "" | ||
| echo "Ensuring JitPack repository in $FILE..." | ||
| if ! grep -q "jitpack.io" "$FILE"; then | ||
| echo "Adding JitPack repository..." | ||
| printf '\nallprojects {\n repositories {\n maven(url = "https://jitpack.io")\n }\n}\n' >> "$FILE" | ||
| fi | ||
| echo "" | ||
| echo "=== ROOT BUILD.GRADLE.KTS AFTER JITPACK ===" | ||
| cat "$FILE" | ||
| fi | ||
|
||
|
|
||
| - name: Upload generated Android files | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: android-generated-files | ||
| path: | | ||
| src-tauri/gen/android/app/src/main/AndroidManifest.xml | ||
| src-tauri/gen/android/app/src/main/res/xml/device_filter.xml | ||
| src-tauri/gen/android/app/build.gradle.kts | ||
| src-tauri/gen/android/build.gradle.kts | ||
| retention-days: 7 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| # Android USB Serial Support | ||
|
|
||
| # Android USB Serial Support | ||
|
|
||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ## Current Status (v2.16.0) | ||
|
|
||
| The `tauri-plugin-serialplugin` version 2.16.0 includes Android support with Kotlin implementation for USB serial communication. However, USB devices may not be detected due to runtime permission handling. | ||
|
|
||
| ## What's Working | ||
|
|
||
| ✅ **Build**: APK compiles successfully | ||
| ✅ **Manifest Permissions**: USB permissions are patched into AndroidManifest.xml | ||
| ✅ **Plugin**: Version 2.16.0 has Android Kotlin code | ||
| ✅ **Dependencies**: `usb-serial-for-android` library is added via Gradle | ||
| ✅ **Device Filter**: USB device VID/PID filter is created | ||
|
|
||
| ## What May Not Be Working | ||
|
|
||
| ❌ **Runtime Permission Request**: Android requires explicit permission request when USB device is attached | ||
| ❌ **Port Detection**: USB ports may not appear without proper UsbManager usage | ||
|
|
||
| ## The Problem | ||
|
|
||
| Even with manifest permissions, Android apps need to: | ||
| 1. **Request permission at runtime** when a USB device is detected | ||
| 2. **Use Android's UsbManager** to enumerate connected USB devices | ||
| 3. **Handle USB_DEVICE_ATTACHED intent** to detect when devices are plugged in | ||
|
|
||
| The plugin version 2.16.0 has Kotlin code for this, but it may need: | ||
| - Proper initialization in MainActivity | ||
| - USB permission dialog handling | ||
| - Event bridging between Android and Tauri | ||
|
|
||
| ## Usage | ||
|
|
||
| ### Building for Android | ||
|
|
||
| 1. Initialize the Android project (if not already done): | ||
| ```bash | ||
| cd src-tauri | ||
| cargo tauri android init | ||
| ``` | ||
|
|
||
| 2. **Run the patch script** before building: | ||
| ```bash | ||
| ./scripts/patch-android-manifest.sh | ||
| ``` | ||
|
|
||
| 3. Build the Android APK: | ||
| ```bash | ||
| cd src-tauri | ||
| cargo tauri android build | ||
| ``` | ||
|
|
||
| ### Automated Workflow | ||
|
|
||
| You can combine these steps: | ||
|
|
||
| ```bash | ||
| # From the project root | ||
| cd src-tauri | ||
| cargo tauri android init | ||
| cd .. | ||
| ./scripts/patch-android-manifest.sh | ||
| cd src-tauri | ||
| cargo tauri android build | ||
| ``` | ||
|
|
||
| ## What the Script Does | ||
|
|
||
| 1. Checks if the Android manifest exists at `src-tauri/gen/android/app/src/main/AndroidManifest.xml` | ||
| 2. Adds USB permissions if not already present | ||
| 3. Adds USB device attach intent filter | ||
| 4. Creates `device_filter.xml` with all Betaflight-compatible USB device IDs | ||
| 5. Creates a backup of the original manifest | ||
|
|
||
| ## Future Improvements | ||
|
|
||
| Ideally, `tauri-plugin-serialplugin` should handle Android permissions automatically. If this becomes available in a future version, this workaround will no longer be necessary. | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Script fails with "manifest not found" | ||
| Run `cargo tauri android init` first to generate the Android project. | ||
|
|
||
| ### Permissions not working after build | ||
| Make sure you run the patch script **after** `android init` but **before** `android build`. | ||
|
|
||
| ### Need to rebuild | ||
| If you run `cargo tauri android init` again (which regenerates the manifest), you must run the patch script again before building. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| # Android USB Debugging Guide | ||
|
|
||
| ## Current Situation | ||
|
|
||
| **Status**: APK builds and installs, but app doesn't prompt for USB permission when device is attached | ||
|
|
||
| **Critical Finding**: The app not prompting for USB permission means the **intent filter is likely not being added** to the manifest. This could be due to: | ||
| 1. The `sed -i` command failing on different platforms (macOS vs Linux) | ||
| 2. The intent filter not being inserted in the right place | ||
| 3. The patch script running but failing silently | ||
|
|
||
| **What We Know**: | ||
| - ✅ Build succeeds without errors | ||
| - ✅ Plugin v2.16.0 has Android Kotlin code | ||
| - ✅ Manifest patch script is called in CI | ||
| - ❌ App doesn't prompt for USB device handling when device attached | ||
| - ❌ No ports show in the UI | ||
|
|
||
| ## Investigation Steps | ||
|
|
||
| ### 1. Verify Manifest Patching (FIRST PRIORITY) | ||
|
|
||
| Run the test workflow: | ||
| ```bash | ||
| # Push the test workflow | ||
| git add .github/workflows/test-android-patch.yml | ||
| git commit -m "Add manifest patching test workflow" | ||
| git push | ||
|
|
||
| # Then go to GitHub Actions and run "Test Android Patch" manually | ||
| ``` | ||
|
|
||
| Check the workflow output for: | ||
| - `BEFORE patch:` section should show unpatched manifest | ||
| - `AFTER patch:` section should show USB permissions | ||
| - `device_filter.xml` should exist with VID/PID entries | ||
| - `build.gradle.kts` should have usb-serial-for-android dependency | ||
|
|
||
| ### 2. Check Your USB Device VID/PID | ||
|
|
||
| On your Linux machine with the flight controller connected: | ||
| ```bash | ||
| lsusb | ||
| ``` | ||
|
|
||
| Look for output like: | ||
| ``` | ||
haslinghuis marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Bus 001 Device 005: ID 0483:5740 STMicroelectronics Virtual COM Port | ||
| ^^^^ ^^^^ | ||
| VID PID | ||
| ``` | ||
|
|
||
| Verify this VID/PID combination is in `device_filter.xml`: | ||
| ```xml | ||
| <usb-device vendor-id="0x0483" product-id="0x5740"/> | ||
| ``` | ||
|
|
||
| If your device isn't listed, we need to add it to the patch script. | ||
|
|
||
| ### 3. Check Plugin Initialization | ||
|
|
||
| The plugin should auto-initialize on Android, but we can verify by checking the Rust code: | ||
|
|
||
| **Current initialization** (src-tauri/src/main.rs): | ||
| ```rust | ||
| .plugin(tauri_plugin_serialplugin::init()) | ||
| ``` | ||
|
|
||
| This should work, but the plugin may need the Android UsbManager to be explicitly initialized. | ||
|
|
||
| ### 4. Potential Issues | ||
|
|
||
| #### Issue A: Runtime Permission Not Requested | ||
| Android requires apps to request USB permission at runtime, not just declare it in the manifest. The plugin's Kotlin code should handle this, but it may need: | ||
|
|
||
| ```kotlin | ||
| // In MainActivity.kt or plugin initialization | ||
| val usbManager = getSystemService(Context.USB_SERVICE) as UsbManager | ||
| val permissionIntent = PendingIntent.getBroadcast(this, 0, Intent(ACTION_USB_PERMISSION), 0) | ||
| usbManager.requestPermission(device, permissionIntent) | ||
| ``` | ||
|
|
||
| #### Issue B: Plugin Not Using usb-serial-for-android | ||
| The plugin may have its own USB implementation that conflicts with usb-serial-for-android. We need to verify the plugin actually uses this library. | ||
|
|
||
| #### Issue C: Port Enumeration Timing | ||
| Ports may need to be enumerated AFTER USB permission is granted. The app may need to: | ||
| 1. Wait for USB_DEVICE_ATTACHED broadcast | ||
| 2. Request permission via dialog | ||
| 3. THEN enumerate ports after permission granted | ||
|
|
||
| ### 5. Next Steps | ||
|
|
||
| 1. **Run test workflow** to verify patches are applied | ||
| 2. **Check device VID/PID** matches filter | ||
| 3. **Review plugin source code** at https://github.com/s00d/tauri-plugin-serialplugin/tree/main/android | ||
| 4. **Add logging** to see what the plugin sees: | ||
| - Is UsbManager finding devices? | ||
| - Is permission actually granted? | ||
| - Does the plugin call port enumeration after permission? | ||
|
|
||
| ### 6. Workaround: Custom Android Code | ||
|
|
||
| If the plugin doesn't properly handle USB, we may need to add custom Android code: | ||
|
|
||
| **Option 1**: Fork and patch the plugin | ||
| **Option 2**: Add custom Kotlin code to MainActivity | ||
| **Option 3**: Use a different approach (WebUSB, custom serial implementation) | ||
|
|
||
| ## Key Files | ||
|
|
||
| - `scripts/patch-android-manifest.sh` - Adds USB permissions and filters | ||
| - `src-tauri/gen/android/app/src/main/AndroidManifest.xml` - Generated manifest (check after patch) | ||
| - `src-tauri/gen/android/app/src/main/res/xml/device_filter.xml` - USB VID/PID filter | ||
| - `src-tauri/gen/android/app/build.gradle.kts` - Should have usb-serial-for-android dependency | ||
|
|
||
| ## Supported USB Chips (Currently in device_filter.xml) | ||
|
|
||
| - FTDI (VID: 0x0403) | ||
| - STM32 Virtual COM (VID: 0x0483) | ||
| - Silicon Labs CP210x (VID: 0x10c4) | ||
| - GD32 (VID: 0x28e9) | ||
| - AT32 (VID: 0x2e3c) | ||
| - APM32 (VID: 0x314b) | ||
| - Raspberry Pi Pico (VID: 0x2e8a) | ||
|
|
||
| If your device isn't listed, add it to `patch-android-manifest.sh` in the device_filter.xml section. | ||
Uh oh!
There was an error while loading. Please reload this page.