-
-
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
Open
haslinghuis
wants to merge
56
commits into
betaflight:tauri
Choose a base branch
from
haslinghuis:tauri-test
base: tauri
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+2,193
−595
Open
Patch manifest #4687
Changes from 21 commits
Commits
Show all changes
56 commits
Select commit
Hold shift + click to select a range
fc31a5e
Patch manifest
haslinghuis ae221c4
Updte workflow
haslinghuis b6b31db
Use tauri-plugin-serialplugin
haslinghuis 74a3266
Fix build
haslinghuis 983a9cf
Use Kotlin DSL syntax, not Groovy
haslinghuis c2163bd
Replace sed with awk
haslinghuis 0533869
Downgrade tauri-plugin-serialplugin to 2.10.0 in Cargo.lock
haslinghuis a801f59
Upgrade to tauri-plugin-serialplugin 2.16.0 for Android USB support
haslinghuis cadf39f
Add Android USB debugging tools and updated documentation
haslinghuis eb441f4
Fix manifest patching: replace sed with awk for cross-platform compat…
haslinghuis 8c93e03
Add custom MainActivity with USB runtime permission handling
haslinghuis b1c3154
Update debugging docs with MainActivity testing instructions
haslinghuis 0a60f3e
Fix MainActivity import: add missing TauriActivity import
haslinghuis 2eb9aaa
Nitpicks
haslinghuis cd6aa1f
Fix JitPack repository injection: use settings.gradle.kts with Kotlin…
haslinghuis 2f2e9ab
Move JitPack repository injection into patch script
haslinghuis e9c511e
Inject JitPack into dependencyResolutionManagement.repositories in se…
haslinghuis 3d13b6e
Revert usb-serial-for-android to 3.8.0 and harden JitPack injection
haslinghuis d71a7c1
Fix grep alternation and duplicate -n in JitPack repo preview
haslinghuis 04b8256
Force usb-serial-for-android to 3.8.0 and remove FAIL_ON_PROJECT_REPO…
haslinghuis 99642e8
Fix Kotlin DSL syntax error - use resolutionStrategy instead of isForce
haslinghuis aa9ddc8
Add debug output to show settings.gradle.kts before and after JitPack…
haslinghuis 8d87c20
Add JitPack repository directly to app build.gradle.kts as fallback
haslinghuis 37fb1b6
Remove custom MainActivity - not needed for USB serial permissions
haslinghuis 6d79317
Add extensive debug logging for Android USB enumeration
haslinghuis a826b93
Add ADB wireless debugging setup for Android USB testing
haslinghuis 4a32b85
Fix ADB wireless setup script to support IPv6 addresses
haslinghuis b85212b
Add comprehensive next steps guide for Android USB debugging
haslinghuis 792d918
Add local Android build script: init + patch + dev/release + signing …
haslinghuis 735ac48
feat(android): enable USB serial support with debugging capabilities
haslinghuis 1d19205
docs: add Android USB serial status and progress tracking
haslinghuis 9416e32
Shell improvement
haslinghuis 1331237
Default is not needed when using explicit permissions
haslinghuis 4435a99
No need for HMR_HOST
haslinghuis bb84552
Forgot to include
haslinghuis 90cecf7
Address 'Warning: src-tauri/gen/android/settings.gradle.kts not found…
haslinghuis 83122fc
Address 'Warning: src-tauri/gen/android/settings.gradle.kts not found…
haslinghuis 7e03458
little cleanup
haslinghuis b7f391a
Update scripts
haslinghuis 0a0bf83
Fix android debugging
haslinghuis 62f9c41
???
haslinghuis 05bc006
Add dependency for usb-serial-for-android
haslinghuis 5ec9332
Address CR nitpick
haslinghuis cb3680a
After running cargo update
haslinghuis 5f31190
Fix working versions
haslinghuis a93186b
Dependency hell
haslinghuis 8e779cd
Which version works ???
haslinghuis 72173cf
Fix script portability
haslinghuis 56f041f
modify the patch script to add the repository directly to build.gradl…
haslinghuis 4dfd15e
refactor scripts for single responsibility
haslinghuis c19e84c
Using js API instead of Rust invoke
haslinghuis bf62596
Fix USB permission issue
haslinghuis 220037c
Fix port enumeration
haslinghuis 0e4c4c7
Some cleanup
haslinghuis 6dea4b3
Read is not solved
haslinghuis 7e5ce52
Apply custom MainActivity.kt
haslinghuis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 files after patch | ||
| run: | | ||
| echo "=== AndroidManifest.xml AFTER patch ===" | ||
| cat src-tauri/gen/android/app/src/main/AndroidManifest.xml | ||
| echo "" | ||
| echo "=== Checking for USB permissions ===" | ||
| grep -i "usb" src-tauri/gen/android/app/src/main/AndroidManifest.xml || echo "No USB permissions found!" | ||
| echo "" | ||
| echo "=== device_filter.xml ===" | ||
| cat src-tauri/gen/android/app/src/main/res/xml/device_filter.xml || echo "device_filter.xml not found!" | ||
| echo "" | ||
| echo "=== MainActivity.kt ===" | ||
| cat src-tauri/gen/android/app/src/main/java/com/betaflight/configurator/MainActivity.kt || echo "MainActivity.kt not found!" | ||
| echo "" | ||
| echo "=== app/build.gradle.kts dependencies ===" | ||
| grep -A 10 "dependencies {" src-tauri/gen/android/app/build.gradle.kts || echo "No dependencies block 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 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| # Android USB Serial Support | ||
|
|
||
| ## Current Status (v2.16.0) | ||
|
|
||
| The `tauri-plugin-serialplugin` version 2.16.0 includes Android support, but requires additional runtime permission handling to actually detect USB devices. | ||
|
|
||
| ## 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 | ||
| ✅ **Intent Filter**: App launches when USB device is attached | ||
|
|
||
| ## Custom MainActivity | ||
|
|
||
| We've added a custom `MainActivity.kt` that handles USB permission requests properly: | ||
|
|
||
| ### What it does: | ||
| 1. **Registers USB broadcast receivers** for device attach/detach events | ||
| 2. **Automatically requests permission** when a USB device is detected | ||
| 3. **Checks for already connected devices** on app launch | ||
| 4. **Handles the permission dialog** and logs the result | ||
| 5. **Manages app lifecycle** (onCreate, onDestroy, onNewIntent) | ||
|
|
||
| ### How it works: | ||
| ```kotlin | ||
| // When USB device is attached: | ||
| 1. Android broadcasts ACTION_USB_DEVICE_ATTACHED | ||
| 2. MainActivity receives the broadcast | ||
| 3. Checks if we have permission for the device | ||
| 4. If not, shows permission dialog to user | ||
| 5. User grants/denies permission | ||
| 6. Result is broadcast back to MainActivity | ||
| 7. Plugin can now enumerate and open the port | ||
| ``` | ||
|
|
||
| ## The Problem We Solved | ||
|
|
||
| Even with manifest permissions, Android apps need to **request permission at runtime** for each USB device. The stock Tauri activity doesn't do this automatically, so we added: | ||
|
|
||
| - Custom `MainActivity.kt` that extends `TauriActivity` | ||
| - USB broadcast receivers for attach/detach events | ||
| - Runtime permission request handling | ||
| - Logging to help debug USB issues | ||
|
|
||
| ## 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. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Fix JitPack repository injection: target settings.gradle.kts and Kotlin DSL syntax
Appending an allprojects block to build.gradle.kts is discouraged in Gradle 8+ and often ignored when repositoriesMode FAIL_ON_PROJECT_REPOS is enabled. Also, maven(url = "...") is not idiomatic Kotlin DSL. Patch settings.gradle.kts under dependencyResolutionManagement instead.
Apply this diff to replace the step and use Kotlin DSL:
Run to confirm where repositories are sourced:
🏁 Script executed:
Length of output: 0
🏁 Script executed:
Length of output: 163
🏁 Script executed:
Length of output: 3674
🌐 Web query:
💡 Result:
Short answer — what
tauri android initproduces and what goes in settings.gradle.ktsThe Android project is generated at src-tauri/gen/android as a Gradle multi-project (root + modules).
settings.gradle.ktslives at that generated android root and declares the included modules and repository resolution rules. [1][2]Typical responsibilities of settings.gradle.kts in a Tauri-generated project:
:tauri-android/:tauri).Minimal example (Kotlin DSL) you can expect or copy into the generated android root:
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
(Adapt module names to whatever
src-tauri/gen/androidcontains.) [1][2]Notes:
Sources
🌐 Web query:
💡 Result:
Short examples for declaring Maven repositories in Gradle Kotlin DSL (build.gradle.kts or settings.gradle.kts):
common built-ins
repositories {
mavenCentral()
mavenLocal()
google()
}
[1]
custom Maven URL (build.gradle.kts)
repositories {
maven {
url = uri("https://my.repo.example/maven")
}
}
[1][2]
with name + credentials (username/password)
repositories {
maven {
name = "MyRepo"
url = uri("https://my.repo.example/maven")
credentials(PasswordCredentials::class) {
username = findProperty("repoUser") as String?
password = findProperty("repoPassword") as String?
}
}
}
[2]
token/HTTP-header auth example (GitLab style)
val gitLabToken: String by project
repositories {
maven {
url = uri("https://gitlab.com/api/v4/projects/12345/packages/maven")
name = "GitLab"
credentials(org.gradle.plugin.auth.HttpHeaderCredentials::class) {
name = "Private-Token"
value = gitLabToken
}
authentication { create<org.gradle.plugin.auth.HttpHeaderAuthentication>("header") }
}
}
[3]
centralizing in settings.gradle.kts (dependencyResolutionManagement)
dependencyResolutionManagement {
repositories {
mavenCentral()
maven { url = uri("https://my.repo.example/maven") }
}
}
[1][3]
References:
Fix JitPack repository injection: target settings.gradle.kts with correct Kotlin DSL syntax
The original approach appends
allprojectsto build.gradle.kts using Groovy syntax, which is incompatible with Kotlin DSL (.kts) files and ignored in Gradle 8+ whenrepositoriesMode.FAIL_ON_PROJECT_REPOSis enabled. The correct target issettings.gradle.ktsunderdependencyResolutionManagement.However, the proposed fix also contains incorrect Kotlin DSL syntax. In Kotlin DSL, the correct syntax is
maven { url = uri("https://jitpack.io") }, notmaven("url").Replace the step with:
- name: Ensure JitPack repository (settings.gradle.kts) shell: bash run: | set -euo pipefail FILE="src-tauri/gen/android/settings.gradle.kts" if [ -f "$FILE" ]; then echo "=== settings.gradle.kts BEFORE JITPACK ===" cat "$FILE"; echo "" if grep -q 'dependencyResolutionManagement' "$FILE"; then if ! grep -q 'https://jitpack.io' "$FILE"; then echo "Adding JitPack to dependencyResolutionManagement.repositories..." sed -i '/repositories\s*{/a\ maven { url = uri("https://jitpack.io") }' "$FILE" fi else printf '\ndependencyResolutionManagement {\n repositories {\n mavenCentral()\n google()\n maven { url = uri("https://jitpack.io") }\n }\n}\n' >> "$FILE" fi echo "=== settings.gradle.kts AFTER JITPACK ===" cat "$FILE" fi🤖 Prompt for AI Agents